// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------
// Modification history:
// feature: support e2e deadline and liveliness: 1. xml support e2e_deadline and e2e_liveliness config 2. data writer and data reader support e2e deadline and e2e liveliness qos
// feature: add multi-domain support for discovery server
// feature: change E2E packet format
// feature: suport super-client
// feature: modify log level
// feature: another method of counting packet lost
// feature: destination order support by reception timestamp
// feature: QoS Profile Inheritance and Composition
// feature: simplify xml profile
// feature: E2E Profile04 and Configuration Function Development
// feature: compatible with DSF
// feature: flowcontroller xml config and writer/reader-resourcelimit
// ------------------------------------------------------------------

#include <xmlparser/XMLParserCommonPart.h>
#include <xmlparser/XMLParserPart.h>
#include <xmlparser/XMLProfileManagerPart.h>
#include <deps/common/IPLocator.h>
#include <elog/Log.hpp>
#include <deps/common/Types.h>

#include <tinyxml2.h>
#include <cstring>
#include <regex>
#include <string>
#include <unordered_map>
#include <climits>

#include <asio.hpp>
#include <unistd.h>

namespace vbsutil {
namespace xmlparser {

std::string XMLParserpart::getAttributeName(const char* name, tinyxml2::XMLElement* elem) {
    std::string profile_name;
    const tinyxml2::XMLAttribute* attrib;
    for (attrib = elem->FirstAttribute(); attrib != nullptr; attrib = attrib->Next()) {
        if (strcmp(attrib->Name(), name) == 0) {
            profile_name = attrib->Value();
            break;
        }
    }
    return profile_name;
}

XMLP_ret XMLParserpart::getXMLTransports(tinyxml2::XMLElement* elem, std::vector<std::string>& transports,
                                         std::vector<std::shared_ptr<TransportDescriptorInterfacePart>>& transportsDSF,
                                         uint8_t) {
    tinyxml2::XMLElement* p_aux0 = nullptr;
    p_aux0 = elem->FirstChildElement(xmlString::TRANSPORT_ID);
    if (nullptr == p_aux0) {
        elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER, "Node '" << elem->Value() << "' without content");
        return XMLP_ret::XML_ERROR;
    }

    while (nullptr != p_aux0) {
        const char* text = p_aux0->GetText();
        if (nullptr == text) {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Node '" << xmlString::TRANSPORT_ID << "' without content");
            return XMLP_ret::XML_ERROR;
        } else {
            transports.push_back(text);  // 当前只保存字符串信息，解析函数 fillTransportAttributes
            XMLProfileManagerPart::userTransportsId.push_back(text);  // 保存信息，用于解析传输层模板时进行校验
            std::shared_ptr<TransportDescriptorInterfacePart> pDescriptor =
                XMLProfileManagerPart::getTransportById(text);
            if (pDescriptor != nullptr) {
                transportsDSF.emplace_back(pDescriptor);
            }
        }
        p_aux0 = p_aux0->NextSiblingElement(xmlString::TRANSPORT_ID);
    }

    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLSnippetProfileAttributes(tinyxml2::XMLElement* elem, const std::string& profile_name) {
    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;
    auto& stored_part_profiles = XMLProfileManagerPart::participant_profiles_;
    auto& stored_part_set_flags = XMLProfileManagerPart::participant_profile_set_flags_;
    auto& stored_pub_profiles = XMLProfileManagerPart::publisher_profiles_;
    auto& stored_pub_set_flags = XMLProfileManagerPart::publisher_profile_set_flags_;
    auto& stored_sub_profiles = XMLProfileManagerPart::subscriber_profiles_;
    auto& stored_sub_set_flags = XMLProfileManagerPart::subscriber_profile_set_flags_;

    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::VALUE) == 0) {
            bool has_found = false;
            std::string snippet_profile_name = p_aux0->GetText();
            if (stored_part_profiles.find(snippet_profile_name) != stored_part_profiles.end()) {
                if (stored_part_set_flags.find(snippet_profile_name) != stored_part_set_flags.end()) {
                    auto& snippet_profile = stored_part_profiles[snippet_profile_name];
                    auto& snippet_set_flags = stored_part_set_flags[snippet_profile_name];
                    ParticipantAttributes* participant = nullptr;
                    if (stored_part_profiles.find(profile_name) != stored_part_profiles.end()) {
                        participant = stored_part_profiles[profile_name].get();
                    } else {
                        up_participant_t participant_ptr(new ParticipantAttributes());
                        participant = participant_ptr.get();
                        stored_part_profiles.emplace(profile_name, std::move(participant_ptr));
                        std::vector<bool> set_flags(ParticipantConfigKind::PART_CONFIG_END);
                        stored_part_set_flags[profile_name] = snippet_set_flags;
                    }
                    participantProfileCompareToUpdate(participant, stored_part_set_flags[profile_name],
                                                      snippet_profile.get(), snippet_set_flags);
                    logDebug(XMLPARSER,
                             "Profile snippet '" << snippet_profile_name << "' add to '" << profile_name << "'.");
                    has_found = true;
                }
            }

            if (stored_pub_profiles.find(snippet_profile_name) != stored_pub_profiles.end()) {
                if (stored_pub_set_flags.find(snippet_profile_name) != stored_pub_set_flags.end()) {
                    auto& snippet_profile = stored_pub_profiles[snippet_profile_name];
                    auto& snippet_set_flags = stored_pub_set_flags[snippet_profile_name];
                    PublisherAttributes* publisher = nullptr;
                    if (stored_pub_profiles.find(profile_name) != stored_pub_profiles.end()) {
                        publisher = stored_pub_profiles[profile_name].get();
                    } else {
                        up_publisher_t publisher_ptr(new PublisherAttributes());
                        publisher = publisher_ptr.get();
                        stored_pub_profiles.emplace(profile_name, std::move(publisher_ptr));
                        std::vector<bool> set_flags(PublisherConfigKind::PUB_CONFIG_END);
                        stored_pub_set_flags[profile_name] = snippet_set_flags;
                    }
                    publisherProfileCompareToUpdate(publisher, stored_pub_set_flags[profile_name],
                                                    snippet_profile.get(), snippet_set_flags);
                    logDebug(XMLPARSER,
                             "Profile snippet '" << snippet_profile_name << "' add to '" << profile_name << "'.");
                    has_found = true;
                }
            }

            if (stored_sub_profiles.find(snippet_profile_name) != stored_sub_profiles.end()) {
                if (stored_sub_set_flags.find(snippet_profile_name) != stored_sub_set_flags.end()) {
                    auto& snippet_profile = stored_sub_profiles[snippet_profile_name];
                    auto& snippet_set_flags = stored_sub_set_flags[snippet_profile_name];
                    SubscriberAttributes* subscriber = nullptr;
                    if (stored_sub_profiles.find(profile_name) != stored_sub_profiles.end()) {
                        subscriber = stored_sub_profiles[profile_name].get();
                    } else {
                        up_subscriber_t subscriber_ptr(new SubscriberAttributes());
                        subscriber = subscriber_ptr.get();
                        stored_sub_profiles.emplace(profile_name, std::move(subscriber_ptr));
                        std::vector<bool> set_flags(SubscriberConfigKind::SUB_CONFIG_END);
                        stored_sub_set_flags[profile_name] = snippet_set_flags;
                    }
                    subscriberProfileCompareToUpdate(subscriber, stored_sub_set_flags[profile_name],
                                                     snippet_profile.get(), snippet_set_flags);
                    logDebug(XMLPARSER,
                             "Profile snippet '" << snippet_profile_name << "' add to '" << profile_name << "'.");
                    has_found = true;
                }
            }
            if (has_found == false) {
                elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA,
                          "Profile snippet'" << snippet_profile_name << "' not found or invalid when adding to '"
                                             << profile_name << "'");
                return XMLP_ret::XML_ERROR;
            }
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_UNSUPPORTED,
                      "Invalid element found into base_name of participant profile. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }
    return XMLP_ret::XML_OK;
}

void XMLParserpart::participantProfileCompareToUpdate(ParticipantAttributes* part_attr, std::vector<bool>& set_flags,
                                                      ParticipantAttributes* snippet_part_attr,
                                                      std::vector<bool>& snippet_set_flags) {
    // domain id
    if (snippet_set_flags[ParticipantConfigKind::PART_CONFIG_DOMAIN_ID]) {
        part_attr->domainId = snippet_part_attr->domainId;
        set_flags[ParticipantConfigKind::PART_CONFIG_DOMAIN_ID] = true;
    }
    // allocation
    if (snippet_set_flags[ParticipantConfigKind::PART_CONFIG_ALLOCATION]) {
        part_attr->rtps.allocation = snippet_part_attr->rtps.allocation;
        set_flags[ParticipantConfigKind::PART_CONFIG_ALLOCATION] = true;
    }
    // prefix
    if (snippet_set_flags[ParticipantConfigKind::PART_CONFIG_PREFIX]) {
        part_attr->rtps.prefix = snippet_part_attr->rtps.prefix;
        set_flags[ParticipantConfigKind::PART_CONFIG_PREFIX] = true;
    }
    // ignore_non_matching_locators
    if (snippet_set_flags[ParticipantConfigKind::PART_CONFIG_IGN_NON_MATCHING_LOCS]) {
        part_attr->rtps.ignore_non_matching_locators = snippet_part_attr->rtps.ignore_non_matching_locators;
        set_flags[ParticipantConfigKind::PART_CONFIG_IGN_NON_MATCHING_LOCS] = true;
    }
    // default_external_unicast_locators
    if (snippet_set_flags[ParticipantConfigKind::PART_CONFIG_DEF_EXT_UNI_LOC_LIST]) {
        part_attr->rtps.default_external_unicast_locators = snippet_part_attr->rtps.default_external_unicast_locators;
        set_flags[ParticipantConfigKind::PART_CONFIG_DEF_EXT_UNI_LOC_LIST] = true;
    }
    // defaultUnicastLocatorList
    if (snippet_set_flags[ParticipantConfigKind::PART_CONFIG_DEF_UNI_LOC_LIST]) {
        part_attr->rtps.defaultUnicastLocatorList = snippet_part_attr->rtps.defaultUnicastLocatorList;
        set_flags[ParticipantConfigKind::PART_CONFIG_DEF_UNI_LOC_LIST] = true;
    }
    // defaultMulticastLocatorList
    if (snippet_set_flags[ParticipantConfigKind::PART_CONFIG_DEF_MULTI_LOC_LIST]) {
        part_attr->rtps.defaultMulticastLocatorList = snippet_part_attr->rtps.defaultMulticastLocatorList;
        set_flags[ParticipantConfigKind::PART_CONFIG_DEF_MULTI_LOC_LIST] = true;
    }
    // sendSocketBufferSize
    if (snippet_set_flags[ParticipantConfigKind::PART_CONFIG_SEND_SOCK_BUF_SIZE]) {
        part_attr->rtps.sendSocketBufferSize = snippet_part_attr->rtps.sendSocketBufferSize;
        set_flags[ParticipantConfigKind::PART_CONFIG_SEND_SOCK_BUF_SIZE] = true;
    }
    // listenSocketBufferSize
    if (snippet_set_flags[ParticipantConfigKind::PART_CONFIG_LIST_SOCK_BUF_SIZE]) {
        part_attr->rtps.listenSocketBufferSize = snippet_part_attr->rtps.listenSocketBufferSize;
        set_flags[ParticipantConfigKind::PART_CONFIG_LIST_SOCK_BUF_SIZE] = true;
    }
    // builtin
    if (snippet_set_flags[ParticipantConfigKind::PART_CONFIG_BUILTIN]) {
        part_attr->rtps.builtin = snippet_part_attr->rtps.builtin;
        set_flags[ParticipantConfigKind::PART_CONFIG_BUILTIN] = true;
    }
    // port
    if (snippet_set_flags[ParticipantConfigKind::PART_CONFIG_PORT]) {
        part_attr->rtps.port = snippet_part_attr->rtps.port;
        set_flags[ParticipantConfigKind::PART_CONFIG_PORT] = true;
    }
    // participantID
    if (snippet_set_flags[ParticipantConfigKind::PART_CONFIG_PART_ID]) {
        part_attr->rtps.participantID = snippet_part_attr->rtps.participantID;
        set_flags[ParticipantConfigKind::PART_CONFIG_PART_ID] = true;
    }
    // userTransports
    if (snippet_set_flags[ParticipantConfigKind::PART_CONFIG_USER_TRANS]) {
        part_attr->rtps.userTransports = snippet_part_attr->rtps.userTransports;
        set_flags[ParticipantConfigKind::PART_CONFIG_USER_TRANS] = true;
    }
    // useBuiltinTransports
    if (snippet_set_flags[ParticipantConfigKind::PART_CONFIG_BUILTIN_TRANS]) {
        part_attr->rtps.useBuiltinTransports = snippet_part_attr->rtps.useBuiltinTransports;
        set_flags[ParticipantConfigKind::PART_CONFIG_BUILTIN_TRANS] = true;
    }
    // transport_type
    if (snippet_set_flags[ParticipantConfigKind::PART_CONFIG_TRANSPORT_TYPE]) {
        part_attr->rtps.transport_type = snippet_part_attr->rtps.transport_type;
        set_flags[ParticipantConfigKind::PART_CONFIG_TRANSPORT_TYPE] = true;
    }
    // properties
    if (snippet_set_flags[ParticipantConfigKind::PART_CONFIG_PROPERTIES_POLICY]) {
        part_attr->rtps.properties = snippet_part_attr->rtps.properties;
        set_flags[ParticipantConfigKind::PART_CONFIG_PROPERTIES_POLICY] = true;
    }
    // flow_controllers
    if (snippet_set_flags[ParticipantConfigKind::PART_CONFIG_FLOW_CONTROLLER]) {
        part_attr->rtps.flow_controllers = snippet_part_attr->rtps.flow_controllers;
        set_flags[ParticipantConfigKind::PART_CONFIG_FLOW_CONTROLLER] = true;
    }
    // name
    if (snippet_set_flags[ParticipantConfigKind::PART_CONFIG_NAME]) {
        part_attr->rtps.setName(snippet_part_attr->rtps.getName());
        set_flags[ParticipantConfigKind::PART_CONFIG_NAME] = true;
    }
}

XMLP_ret XMLParserpart::getXMLSnippetParticipantAttributes(tinyxml2::XMLElement* elem,
                                                           ParticipantAttributes& participant,
                                                           const std::string& profile_name,
                                                           std::vector<bool>& set_flags) {
    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;
    auto& stored_profiles = XMLProfileManagerPart::participant_profiles_;
    auto& stored_set_flags = XMLProfileManagerPart::participant_profile_set_flags_;

    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::VALUE) == 0) {
            std::string snippet_profile_name = p_aux0->GetText();
            if (stored_profiles.find(snippet_profile_name) != stored_profiles.end()) {
                if (stored_set_flags.find(snippet_profile_name) == stored_set_flags.end()) {
                    return XMLP_ret::XML_OK;
                }
                auto& snippet_participant = stored_profiles[snippet_profile_name];
                auto& snippet_set_flags = stored_set_flags[snippet_profile_name];
                participantProfileCompareToUpdate(&participant, set_flags, snippet_participant.get(),
                                                  snippet_set_flags);
                logDebug(XMLPARSER,
                         "Profile snippet '" << snippet_profile_name << "' add to '" << profile_name << "'.");
            } else {
                elogError(XMLPARSER, RetCode_t::RETCODE_ERROR,
                          "Profile snippet'" << snippet_profile_name << "' not found when adding to '" << profile_name
                                             << "'");
                return XMLP_ret::XML_ERROR;
            }
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA,
                      "Invalid element found into base_name of participant profile. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }
    return XMLP_ret::XML_OK;
}

void XMLParserpart::publisherProfileCompareToUpdate(PublisherAttributes* pub_attr, std::vector<bool>& set_flags,
                                                    PublisherAttributes* snippet_pub_attr,
                                                    std::vector<bool>& snippet_set_flags) {
    WriterQos& qos = pub_attr->qos;
    // m_isMultiSend
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_SEND_MULTI]) {
        qos.m_isMultiSend = snippet_pub_attr->qos.m_isMultiSend;
        set_flags[PublisherConfigKind::PUB_CONFIG_SEND_MULTI] = true;
    }
    // m_history
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_HISTORY_QOS]) {
        qos.m_history = snippet_pub_attr->qos.m_history;
        set_flags[PublisherConfigKind::PUB_CONFIG_HISTORY_QOS] = true;
    }
    // m_resourceLimits
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_RES_LIMITS_QOS]) {
        qos.m_resourceLimits = snippet_pub_attr->qos.m_resourceLimits;
        set_flags[PublisherConfigKind::PUB_CONFIG_RES_LIMITS_QOS] = true;
    }
    // m_durability
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_DURABILITY]) {
        qos.m_durability = snippet_pub_attr->qos.m_durability;
        set_flags[PublisherConfigKind::PUB_CONFIG_DURABILITY] = true;
    }
    // m_liveliness
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_LIVELINESS]) {
        qos.m_liveliness = snippet_pub_attr->qos.m_liveliness;
        set_flags[PublisherConfigKind::PUB_CONFIG_LIVELINESS] = true;
    }
    // m_reliability
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_RELIABILITY]) {
        qos.m_reliability = snippet_pub_attr->qos.m_reliability;
        set_flags[PublisherConfigKind::PUB_CONFIG_RELIABILITY] = true;
    }
    // m_partition
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_PARTITION]) {
        qos.m_partition = snippet_pub_attr->qos.m_partition;
        set_flags[PublisherConfigKind::PUB_CONFIG_PARTITION] = true;
    }
    // m_publishMode
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_PUB_MODE]) {
        qos.m_publishMode = snippet_pub_attr->qos.m_publishMode;
        set_flags[PublisherConfigKind::PUB_CONFIG_PUB_MODE] = true;
    }
    // m_deadline
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_DEADLINE]) {
        qos.m_deadline = snippet_pub_attr->qos.m_deadline;
        set_flags[PublisherConfigKind::PUB_CONFIG_DEADLINE] = true;
    }
    // m_lifespan
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_LIFESPAN]) {
        qos.m_lifespan = snippet_pub_attr->qos.m_lifespan;
        set_flags[PublisherConfigKind::PUB_CONFIG_LIFESPAN] = true;
    }
    // m_disablePositiveACKs
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_DISABLE_POSITIVE_ACKS]) {
        qos.m_disablePositiveACKs = snippet_pub_attr->qos.m_disablePositiveACKs;
        set_flags[PublisherConfigKind::PUB_CONFIG_DISABLE_POSITIVE_ACKS] = true;
    }
    // m_ownership
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_OWNERSHIP]) {
        qos.m_ownership = snippet_pub_attr->qos.m_ownership;
        set_flags[PublisherConfigKind::PUB_CONFIG_OWNERSHIP] = true;
    }
    // m_ownershipStrength
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_OWNERSHIP_STRENGTH]) {
        qos.m_ownershipStrength = snippet_pub_attr->qos.m_ownershipStrength;
        set_flags[PublisherConfigKind::PUB_CONFIG_OWNERSHIP_STRENGTH] = true;
    }
#ifdef BATCH_SEND_ENABLE
    // m_batch
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_BATCH]) {
        qos.m_batch = snippet_pub_attr->qos.m_batch;
        set_flags[PublisherConfigKind::PUB_CONFIG_BATCH] = true;
    }
#endif
    // disable_heartbeat_piggyback
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_DISABLE_HEARTBEAT_PIGGYBACK]) {
        qos.disable_heartbeat_piggyback = snippet_pub_attr->qos.disable_heartbeat_piggyback;
        set_flags[PublisherConfigKind::PUB_CONFIG_DISABLE_HEARTBEAT_PIGGYBACK] = true;
    }
    // m_e2eProtecion
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_E2E_FUNCTION]) {
        qos.m_e2eProtecion = snippet_pub_attr->qos.m_e2eProtecion;
        set_flags[PublisherConfigKind::PUB_CONFIG_E2E_FUNCTION] = true;
    }
    // heartbeat_per_max_samples
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_HEARTBEAT_PER_MAX_SAMPLE]) {
        qos.heartbeat_per_max_samples = snippet_pub_attr->qos.heartbeat_per_max_samples;
        set_flags[PublisherConfigKind::PUB_CONFIG_HEARTBEAT_PER_MAX_SAMPLE] = true;
    }
    // times
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_TIMES]) {
        pub_attr->times = snippet_pub_attr->times;
        set_flags[PublisherConfigKind::PUB_CONFIG_TIMES] = true;
    }
    // ignore_non_matching_locators
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_IGN_NON_MATCHING_LOCS]) {
        pub_attr->ignore_non_matching_locators = snippet_pub_attr->ignore_non_matching_locators;
        set_flags[PublisherConfigKind::PUB_CONFIG_IGN_NON_MATCHING_LOCS] = true;
    }
    // external_unicast_locators
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_EXT_UNI_LOC_LIST]) {
        pub_attr->external_unicast_locators = snippet_pub_attr->external_unicast_locators;
        set_flags[PublisherConfigKind::PUB_CONFIG_EXT_UNI_LOC_LIST] = true;
    }
    // unicastLocatorList
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_UNI_LOC_LIST]) {
        pub_attr->unicastLocatorList = snippet_pub_attr->unicastLocatorList;
        set_flags[PublisherConfigKind::PUB_CONFIG_UNI_LOC_LIST] = true;
    }
    // multicastLocatorList
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_MULTI_LOC_LIST]) {
        pub_attr->multicastLocatorList = snippet_pub_attr->multicastLocatorList;
        set_flags[PublisherConfigKind::PUB_CONFIG_MULTI_LOC_LIST] = true;
    }
    // remoteLocatorList
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_REM_LOC_LIST]) {
        pub_attr->remoteLocatorList = snippet_pub_attr->remoteLocatorList;
        set_flags[PublisherConfigKind::PUB_CONFIG_REM_LOC_LIST] = true;
    }
    // historyMemoryPolicy
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_HIST_MEM_POLICY]) {
        pub_attr->historyMemoryPolicy = snippet_pub_attr->historyMemoryPolicy;
        set_flags[PublisherConfigKind::PUB_CONFIG_HIST_MEM_POLICY] = true;
    }
    // properties
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_PROPERTIES_POLICY]) {
        pub_attr->properties = snippet_pub_attr->properties;
        set_flags[PublisherConfigKind::PUB_CONFIG_PROPERTIES_POLICY] = true;
    }
    // userDefinedID
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_USER_DEF_ID]) {
        pub_attr->setUserDefinedID(snippet_pub_attr->getUserDefinedID());
        set_flags[PublisherConfigKind::PUB_CONFIG_USER_DEF_ID] = true;
    }
    // entityID
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_ENTITY_ID]) {
        pub_attr->setEntityID(snippet_pub_attr->getEntityID());
        set_flags[PublisherConfigKind::PUB_CONFIG_ENTITY_ID] = true;
    }
    // matched_subscriber_allocation
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_MATCHED_SUBSCRIBERS_ALLOCATION]) {
        pub_attr->matched_subscriber_allocation = snippet_pub_attr->matched_subscriber_allocation;
        set_flags[PublisherConfigKind::PUB_CONFIG_MATCHED_SUBSCRIBERS_ALLOCATION] = true;
    }
    // high watermark
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_HIGH_WATERMARK]) {
        qos.high_watermark = snippet_pub_attr->qos.high_watermark;
        set_flags[PublisherConfigKind::PUB_CONFIG_HIGH_WATERMARK] = true;
    }
    // low watermark
    if (snippet_set_flags[PublisherConfigKind::PUB_CONFIG_LOW_WATERMARK]) {
        qos.low_watermark = snippet_pub_attr->qos.low_watermark;
        set_flags[PublisherConfigKind::PUB_CONFIG_LOW_WATERMARK] = true;
    }
}

XMLP_ret XMLParserpart::getXMLSnippetPublisherAttributes(tinyxml2::XMLElement* elem, PublisherAttributes& publisher,
                                                         const std::string& profile_name,
                                                         std::vector<bool>& set_flags) {
    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;
    auto& stored_profiles = XMLProfileManagerPart::publisher_profiles_;
    auto& stored_set_flags = XMLProfileManagerPart::publisher_profile_set_flags_;

    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::VALUE) == 0) {
            std::string snippet_profile_name = p_aux0->GetText();
            if (stored_profiles.find(snippet_profile_name) != stored_profiles.end()) {
                if (stored_set_flags.find(snippet_profile_name) == stored_set_flags.end()) {
                    return XMLP_ret::XML_OK;
                }
                auto& snippet_pub = stored_profiles[snippet_profile_name];
                auto& snippet_set_flags = stored_set_flags[snippet_profile_name];
                publisherProfileCompareToUpdate(&publisher, set_flags, snippet_pub.get(), snippet_set_flags);
                logDebug(XMLPARSER,
                         "Profile snippet '" << snippet_profile_name << "' add to '" << profile_name << "'.");
            } else {
                elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA,
                          "Profile snippet'" << snippet_profile_name << "' not found when adding to '" << profile_name
                                             << "'");
                return XMLP_ret::XML_ERROR;
            }
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into base_name of datawriter profile. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }
    return XMLP_ret::XML_OK;
}

void XMLParserpart::subscriberProfileCompareToUpdate(SubscriberAttributes* sub_attr, std::vector<bool>& set_flags,
                                                     SubscriberAttributes* snippet_sub_attr,
                                                     std::vector<bool>& snippet_set_flags) {
    ReaderQos& qos = sub_attr->qos;
    // m_isMultiSend
    if (snippet_set_flags[SubscriberConfigKind::SUB_CONFIG_SEND_MULTI]) {
        qos.m_isMultiSend = snippet_sub_attr->qos.m_isMultiSend;
        set_flags[SubscriberConfigKind::SUB_CONFIG_SEND_MULTI] = true;
    }
    // m_history
    if (snippet_set_flags[SubscriberConfigKind::SUB_CONFIG_HISTORY_QOS]) {
        qos.m_history = snippet_sub_attr->qos.m_history;
        set_flags[SubscriberConfigKind::SUB_CONFIG_HISTORY_QOS] = true;
    }
    // m_resourceLimits
    if (snippet_set_flags[SubscriberConfigKind::SUB_CONFIG_RES_LIMITS_QOS]) {
        qos.m_resourceLimits = snippet_sub_attr->qos.m_resourceLimits;
        set_flags[SubscriberConfigKind::SUB_CONFIG_RES_LIMITS_QOS] = true;
    }
    // m_durability
    if (snippet_set_flags[SubscriberConfigKind::SUB_CONFIG_DURABILITY]) {
        qos.m_durability = snippet_sub_attr->qos.m_durability;
        set_flags[SubscriberConfigKind::SUB_CONFIG_DURABILITY] = true;
    }
    // m_liveliness
    if (snippet_set_flags[SubscriberConfigKind::SUB_CONFIG_LIVELINESS]) {
        qos.m_liveliness = snippet_sub_attr->qos.m_liveliness;
        set_flags[SubscriberConfigKind::SUB_CONFIG_LIVELINESS] = true;
    }
    // m_reliability
    if (snippet_set_flags[SubscriberConfigKind::SUB_CONFIG_RELIABILITY]) {
        qos.m_reliability = snippet_sub_attr->qos.m_reliability;
        set_flags[SubscriberConfigKind::SUB_CONFIG_RELIABILITY] = true;
    }
    // m_partition
    if (snippet_set_flags[SubscriberConfigKind::SUB_CONFIG_PARTITION]) {
        qos.m_partition = snippet_sub_attr->qos.m_partition;
        set_flags[SubscriberConfigKind::SUB_CONFIG_PARTITION] = true;
    }
    // m_deadline
    if (snippet_set_flags[SubscriberConfigKind::SUB_CONFIG_DEADLINE]) {
        qos.m_deadline = snippet_sub_attr->qos.m_deadline;
        set_flags[SubscriberConfigKind::SUB_CONFIG_DEADLINE] = true;
    }
    // m_lifespan
    if (snippet_set_flags[SubscriberConfigKind::SUB_CONFIG_LIFESPAN]) {
        qos.m_lifespan = snippet_sub_attr->qos.m_lifespan;
        set_flags[SubscriberConfigKind::SUB_CONFIG_LIFESPAN] = true;
    }
    // m_disablePositiveACKs
    if (snippet_set_flags[SubscriberConfigKind::SUB_CONFIG_DISABLE_POSITIVE_ACKS]) {
        qos.m_disablePositiveACKs = snippet_sub_attr->qos.m_disablePositiveACKs;
        set_flags[SubscriberConfigKind::SUB_CONFIG_DISABLE_POSITIVE_ACKS] = true;
    }
    // m_ownership
    if (snippet_set_flags[SubscriberConfigKind::SUB_CONFIG_OWNERSHIP]) {
        qos.m_ownership = snippet_sub_attr->qos.m_ownership;
        set_flags[SubscriberConfigKind::SUB_CONFIG_OWNERSHIP] = true;
    }
    // m_e2eProtecion
    if (snippet_set_flags[SubscriberConfigKind::SUB_CONFIG_E2E_FUNCTION]) {
        qos.m_e2eProtecion = snippet_sub_attr->qos.m_e2eProtecion;
        set_flags[SubscriberConfigKind::SUB_CONFIG_E2E_FUNCTION] = true;
    }
    // times
    if (snippet_set_flags[SubscriberConfigKind::SUB_CONFIG_TIMES]) {
        sub_attr->times = snippet_sub_attr->times;
        set_flags[SubscriberConfigKind::SUB_CONFIG_TIMES] = true;
    }
    // ignore_non_matching_locators
    if (snippet_set_flags[SubscriberConfigKind::SUB_CONFIG_IGN_NON_MATCHING_LOCS]) {
        sub_attr->ignore_non_matching_locators = snippet_sub_attr->ignore_non_matching_locators;
        set_flags[SubscriberConfigKind::SUB_CONFIG_IGN_NON_MATCHING_LOCS] = true;
    }
    // external_unicast_locators
    if (snippet_set_flags[SubscriberConfigKind::SUB_CONFIG_EXT_UNI_LOC_LIST]) {
        sub_attr->external_unicast_locators = snippet_sub_attr->external_unicast_locators;
        set_flags[SubscriberConfigKind::SUB_CONFIG_EXT_UNI_LOC_LIST] = true;
    }
    // unicastLocatorList
    if (snippet_set_flags[SubscriberConfigKind::SUB_CONFIG_UNI_LOC_LIST]) {
        sub_attr->unicastLocatorList = snippet_sub_attr->unicastLocatorList;
        set_flags[SubscriberConfigKind::SUB_CONFIG_UNI_LOC_LIST] = true;
    }
    // multicastLocatorList
    if (snippet_set_flags[SubscriberConfigKind::SUB_CONFIG_MULTI_LOC_LIST]) {
        sub_attr->multicastLocatorList = snippet_sub_attr->multicastLocatorList;
        set_flags[SubscriberConfigKind::SUB_CONFIG_MULTI_LOC_LIST] = true;
    }
    // remoteLocatorList
    if (snippet_set_flags[SubscriberConfigKind::SUB_CONFIG_REM_LOC_LIST]) {
        sub_attr->remoteLocatorList = snippet_sub_attr->remoteLocatorList;
        set_flags[SubscriberConfigKind::SUB_CONFIG_REM_LOC_LIST] = true;
    }
    // historyMemoryPolicy
    if (snippet_set_flags[SubscriberConfigKind::SUB_CONFIG_HIST_MEM_POLICY]) {
        sub_attr->historyMemoryPolicy = snippet_sub_attr->historyMemoryPolicy;
        set_flags[SubscriberConfigKind::SUB_CONFIG_HIST_MEM_POLICY] = true;
    }
    // properties
    if (snippet_set_flags[SubscriberConfigKind::SUB_CONFIG_PROPERTIES_POLICY]) {
        sub_attr->properties = snippet_sub_attr->properties;
        set_flags[SubscriberConfigKind::SUB_CONFIG_PROPERTIES_POLICY] = true;
    }
    // userDefinedID
    if (snippet_set_flags[SubscriberConfigKind::SUB_CONFIG_USER_DEF_ID]) {
        sub_attr->setUserDefinedID(snippet_sub_attr->getUserDefinedID());
        set_flags[SubscriberConfigKind::SUB_CONFIG_USER_DEF_ID] = true;
    }
    // entityID
    if (snippet_set_flags[SubscriberConfigKind::SUB_CONFIG_ENTITY_ID]) {
        sub_attr->setEntityID(snippet_sub_attr->getEntityID());
        set_flags[SubscriberConfigKind::SUB_CONFIG_ENTITY_ID] = true;
    }
    // matched_publisher_allocation
    if (snippet_set_flags[SubscriberConfigKind::SUB_CONFIG_MATCHED_PUBLISHERS_ALLOCATION]) {
        sub_attr->matched_publisher_allocation = snippet_sub_attr->matched_publisher_allocation;
        set_flags[SubscriberConfigKind::SUB_CONFIG_MATCHED_PUBLISHERS_ALLOCATION] = true;
    }
    // destination order
    if (snippet_set_flags[SubscriberConfigKind::SUB_CONFIG_DESTINATION_ORDER]) {
        qos.m_destinationOrder = snippet_sub_attr->qos.m_destinationOrder;
        set_flags[SubscriberConfigKind::SUB_CONFIG_DESTINATION_ORDER] = true;
    }
}

XMLP_ret XMLParserpart::getXMLSnippetSubscriberAttributes(tinyxml2::XMLElement* elem, SubscriberAttributes& subscriber,
                                                          const std::string& profile_name,
                                                          std::vector<bool>& set_flags) {
    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;
    auto& stored_profiles = XMLProfileManagerPart::subscriber_profiles_;
    auto& stored_set_flags = XMLProfileManagerPart::subscriber_profile_set_flags_;

    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::VALUE) == 0) {
            std::string snippet_profile_name = p_aux0->GetText();
            if (stored_profiles.find(snippet_profile_name) != stored_profiles.end()) {
                if (stored_set_flags.find(snippet_profile_name) == stored_set_flags.end()) {
                    return XMLP_ret::XML_OK;
                }
                auto& snippet_sub = stored_profiles[snippet_profile_name];
                auto& snippet_set_flags = stored_set_flags[snippet_profile_name];
                subscriberProfileCompareToUpdate(&subscriber, set_flags, snippet_sub.get(), snippet_set_flags);
                logDebug(XMLPARSER,
                         "Profile snippet '" << snippet_profile_name << "' add to '" << profile_name << "'.");
            } else {
                elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA,
                          "Profile snippet'" << snippet_profile_name << "' not found when adding to '" << profile_name
                                             << "'");
                return XMLP_ret::XML_ERROR;
            }
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into base_name of datareader profile. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }
    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLParticipantAllocationAttributes(
    tinyxml2::XMLElement* elem, xmlparser::RTPSParticipantAllocationAttributes& allocation, uint8_t ident) {
    /*
        <xs:complexType name="rtpsParticipantAllocationAttributesType">
            <xs:all minOccurs="0">
                <xs:element name="remote_locators" type="remoteLocatorsAllocationConfigType"
       minOccurs="0"/> <xs:element name="total_participants" type="containerAllocationConfigType"
       minOccurs="0"/> <xs:element name="total_readers" type="containerAllocationConfigType"
       minOccurs="0"/> <xs:element name="total_writers" type="containerAllocationConfigType"
       minOccurs="0"/> <xs:element name="send_buffers" type="sendBuffersAllocationConfigType"
       minOccurs="0"/> <xs:element name="max_properties" type="uint32Type" minOccurs="0"/>
                <xs:element name="max_user_data" type="uint32Type" minOccurs="0"/>
                <xs:element name="max_partitions" type="uint32Type" minOccurs="0"/>
            </xs:all>
        </xs:complexType>
     */

    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;
    uint32_t tmp;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::REMOTE_LOCATORS) == 0) {
            // leaseDuration - durationType
            if (XMLP_ret::XML_OK != getXMLRemoteLocatorsAllocationAttributes(p_aux0, allocation.locators, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::TOTAL_PARTICIPANTS) == 0) {
            // total_participants - containerAllocationConfigType
            if (XMLP_ret::XML_OK != getXMLContainerAllocationConfig(p_aux0, allocation.participants, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::TOTAL_READERS) == 0) {
            // total_readers - containerAllocationConfigType
            if (XMLP_ret::XML_OK != getXMLContainerAllocationConfig(p_aux0, allocation.readers, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::TOTAL_WRITERS) == 0) {
            // total_writers - containerAllocationConfigType
            if (XMLP_ret::XML_OK != getXMLContainerAllocationConfig(p_aux0, allocation.writers, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::SEND_BUFFERS) == 0) {
            // send_buffers - sendBuffersAllocationConfigType
            if (XMLP_ret::XML_OK != getXMLSendBuffersAllocationAttributes(p_aux0, allocation.send_buffers, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::MAX_PROPERTIES) == 0) {
            // max number of properties in incoming message - uint32Type
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &tmp, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            allocation.data_limits.max_properties = tmp;
        } else if (strcmp(name, xmlString::MAX_USER_DATA) == 0) {
            // max number of user data in incoming message - uint32Type
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &tmp, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            allocation.data_limits.max_user_data = tmp;
        } else if (strcmp(name, xmlString::MAX_PARTITIONS) == 0) {
            // max number of user data in incoming message - uint32Type
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &tmp, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            allocation.data_limits.max_partitions = tmp;
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'rtpsParticipantAllocationAttributesType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }

    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLRemoteLocatorsAllocationAttributes(
    tinyxml2::XMLElement* elem, xmlparser::RemoteLocatorsAllocationAttributes& allocation, uint8_t ident) {
    /*
        <xs:complexType name="remoteLocatorsAllocationConfigType">
            <xs:all minOccurs="0">
                <xs:element name="max_unicast_locators" type="uint32Type" minOccurs="0"/>
                <xs:element name="max_multicast_locators" type="uint32Type" minOccurs="0"/>
            </xs:all>
        </xs:complexType>
     */

    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;
    uint32_t tmp;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::MAX_UNICAST_LOCATORS) == 0) {
            // max_unicast_locators - uint32Type
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &tmp, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            allocation.max_unicast_locators = tmp;
        } else if (strcmp(name, xmlString::MAX_MULTICAST_LOCATORS) == 0) {
            // max_multicast_locators - uint32Type
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &tmp, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            allocation.max_multicast_locators = tmp;
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_ERROR,
                      "Invalid element found into 'remoteLocatorsAllocationConfigType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }

    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLSendBuffersAllocationAttributes(tinyxml2::XMLElement* elem,
                                                              xmlparser::SendBuffersAllocationAttributes& allocation,
                                                              uint8_t ident) {
    /*
        <xs:complexType name="sendBuffersAllocationConfigType">
            <xs:all minOccurs="0">
                <xs:element name="preallocated_number" type="uint32Type" minOccurs="0"/>
                <xs:element name="dynamic" type="boolType" minOccurs="0"/>
            </xs:all>
        </xs:complexType>
     */

    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;
    uint32_t tmp;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::PREALLOCATED_NUMBER) == 0) {
            // preallocated_number - uint32Type
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &tmp, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            allocation.preallocated_number = tmp;
        } else if (strcmp(name, xmlString::DYNAMIC_LC) == 0) {
            // dynamic - boolType
            bool tmp_bool = false;
            if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &tmp_bool, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            allocation.dynamic = tmp_bool;
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'sendBuffersAllocationConfigType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }

    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLDiscoverySettings(tinyxml2::XMLElement* elem, xmlparser::DiscoverySettings& settings,
                                                uint8_t ident) {
    /*
       <xs:complexType name="discoverySettingsType">
        <xs:all minOccurs="0">
            <xs:element name="discoveryProtocol" type="DiscoveryProtocol" minOccurs="0"/>
            <xs:element name="ignoreParticipantFlags" type="ParticipantFlags" minOccurs="0"/>
            <xs:element name="EDP" type="EDPType" minOccurs="0"/>
            <xs:element name="leaseDuration" type="durationType" minOccurs="0"/>
            <xs:element name="leaseAnnouncement" type="durationType" minOccurs="0"/>
            <xs:element name="simpleEDP" type="simpleEDPType" minOccurs="0"/>
            <xs:element name="clientAnnouncementPeriod" type="durationType" minOccurs="0"/>
            <xs:element name="discoveryServersList" type="DiscoveryServerList" minOccurs="0"/>
            <xs:element name="staticEndpointXMLFilename" type="stringType" minOccurs="0"/>
            <xs:element name="static_edp_xml_config" type="stringType" minOccurs="0"/>
            <xs:element name="isCompatible" type="boolType" minOccurs="0"/>
            <xs:element name="domainIdList" type="domainIdListType" minOccurs="0"/>
        </xs:all>
       </xs:complexType>
     */

    tinyxml2::XMLElement *p_aux0 = nullptr, *p_aux1 = nullptr;
    const char* name = nullptr;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::RTPS_PDP_TYPE) == 0) {
            // discoveryProtocol - DiscoveryProtocol
            if (XMLP_ret::XML_OK != getXMLEnum(p_aux0, &settings.discoveryProtocol, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::IGNORE_PARTICIPANT_FLAGS) == 0) {
            // ignoreParticipantFlags - ParticipantFlags
            if (XMLP_ret::XML_OK != getXMLEnum(p_aux0, &settings.ignoreParticipantFlags, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::_EDP) == 0) {
            /*
                <xs:simpleType name="EDPType">
                    <xs:restriction base="xs:string">
                        <xs:enumeration value="SIMPLE"/>
                        <xs:enumeration value="STATIC"/>
                    </xs:restriction>
                </xs:simpleType>
             */
            const char* text = p_aux0->GetText();
            if (nullptr == text) {
                elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "Node '" << xmlString::_EDP << "' without content");
                return XMLP_ret::XML_ERROR;
            } else if (strcmp(text, xmlString::_SIMPLE) == 0) {
                settings.use_SIMPLE_EndpointDiscoveryProtocol = true;
                settings.use_STATIC_EndpointDiscoveryProtocol = false;
            } else if (strcmp(text, xmlString::_STATIC) == 0) {
                settings.use_SIMPLE_EndpointDiscoveryProtocol = false;
                settings.use_STATIC_EndpointDiscoveryProtocol = true;
            } else {
                elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                          "Node '" << xmlString::_EDP << "' with bad content");
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::LEASEDURATION) == 0) {
            // leaseDuration - durationType
            if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, settings.leaseDuration, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::LEASE_ANNOUNCE) == 0) {
            // leaseAnnouncement - durationType
            if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, settings.leaseDuration_announcementperiod, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::INITIAL_ANNOUNCEMENTS) == 0) {
            // initialAnnouncements - initialAnnouncementsType
            if (XMLP_ret::XML_OK != getXMLInitialAnnouncementsConfig(p_aux0, settings.initial_announcements, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::SIMPLE_EDP) == 0) {
            // simpleEDP
            for (p_aux1 = p_aux0->FirstChildElement(); p_aux1 != nullptr; p_aux1 = p_aux1->NextSiblingElement()) {
                name = p_aux1->Name();
                if (strcmp(name, xmlString::PUBWRITER_SUBREADER) == 0) {
                    // PUBWRITER_SUBREADER - boolType
                    if (XMLP_ret::XML_OK != getXMLBool(p_aux1,
                                                       &settings.m_simpleEDP.use_PublicationWriterANDSubscriptionReader,
                                                       ident + 1)) {
                        return XMLP_ret::XML_ERROR;
                    }
                } else if (strcmp(name, xmlString::PUBREADER_SUBWRITER) == 0) {
                    // PUBREADER_SUBWRITER - boolType
                    if (XMLP_ret::XML_OK != getXMLBool(p_aux1,
                                                       &settings.m_simpleEDP.use_PublicationReaderANDSubscriptionWriter,
                                                       ident + 1)) {
                        return XMLP_ret::XML_ERROR;
                    }
                } else {
                    elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                              "Invalid element found into 'simpleEDP'. Name: " << name);
                    return XMLP_ret::XML_ERROR;
                }
            }
        } else if (strcmp(name, xmlString::CLIENTANNOUNCEMENTPERIOD) == 0) {
            // clientAnnouncementPeriod - durationType
            if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, settings.discoveryServer_client_syncperiod, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::SERVER_LIST) == 0) {
            // discoverServersList - locatorListType
            if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux0, settings.m_DiscoveryServers, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::STATIC_ENDPOINT_XML) == 0) {
            // staticEndpointXMLFilename - stringType
            std::string s = "";
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &s, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            std::string file_name = "file://" + s;
            settings.static_edp_xml_config(file_name.c_str());
        } else if (strcmp(name, xmlString::STATIC_ENDPOINT_XML_URI) == 0) {
            // staticEndpointXMLFilename - stringType
            std::string s = "";
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &s, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            settings.static_edp_xml_config(s.c_str());
        } else if (strcmp(name, xmlString::IS_COMPATIBLE) == 0) {
            // isCompatible - boolType
            if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &settings.is_compatible, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::DOMAIN_ID_LIST) == 0) {
            // domainIdList - domainIdListType
            for (p_aux1 = p_aux0->FirstChildElement(); p_aux1 != nullptr; p_aux1 = p_aux1->NextSiblingElement()) {
                name = p_aux1->Name();
                if (strcmp(name, xmlString::DOMAIN_ID) == 0) {
                    uint32_t domain_id = 0;
                    if (XMLP_ret::XML_OK != getXMLUint(p_aux1, &domain_id, ident + 1)) {
                        return XMLP_ret::XML_ERROR;
                    }
                    settings.domainIDs.push_back(domain_id);
                } else {
                    elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                              "Invalid element found into 'domainIdList'. Name: " << name);
                    return XMLP_ret::XML_ERROR;
                }
            }
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'discoverySettingsType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }

    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLBuiltinAttributes(tinyxml2::XMLElement* elem, BuiltinAttributes& builtin, uint8_t ident) {
    /*
       <xs:complexType name="builtinAttributesType">
        <xs:all minOccurs="0">
            <xs:element name="discovery_config" type="discoverySettingsType" minOccurs="0"/>
            <xs:element name="use_WriterLivelinessProtocol" type="boolType" minOccurs="0"/>
            <xs:element name="metatraffic_external_unicast_locators" type="externalLocatorListType"
       minOccurs="0"/> <xs:element name="metatrafficUnicastLocatorList" type="locatorListType"
       minOccurs="0"/> <xs:element name="metatrafficMulticastLocatorList" type="locatorListType"
       minOccurs="0"/> <xs:element name="initialPeersList" type="locatorListType" minOccurs="0"/>
            <xs:element name="readerHistoryMemoryPolicy" type="historyMemoryPolicyType"
       minOccurs="0"/> <xs:element name="writerHistoryMemoryPolicy" type="historyMemoryPolicyType"
       minOccurs="0"/> <xs:element name="mutation_tries" type="uint32Type" minOccurs="0"/>
        </xs:all>
       </xs:complexType>
     */

    std::unordered_map<std::string, bool> tags_present;

    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();

        if (tags_present[name]) {
            elogError(XMLPARSER, RetCode_t::RETCODE_ILLEGAL_OPERATION,
                      "Duplicated element found in 'builtinAttributesType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
        tags_present[name] = true;

        if (strcmp(name, xmlString::DISCOVERY_SETTINGS) == 0) {
            // discovery_config - DiscoverySettings
            if (XMLP_ret::XML_OK != getXMLDiscoverySettings(p_aux0, builtin.discovery_config, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::WRITER_LVESS_PROTOCOL) == 0) {
            // use_WriterLivelinessProtocol - boolType
            if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &builtin.use_WriterLivelinessProtocol, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::META_EXT_UNI_LOC_LIST) == 0) {
            // metatraffic_external_unicast_locators - externalLocatorListType
            if (XMLP_ret::XML_OK !=
                getXMLExternalLocatorList(p_aux0, builtin.metatraffic_external_unicast_locators, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::META_UNI_LOC_LIST) == 0) {
            // metatrafficUnicastLocatorList
            if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux0, builtin.metatrafficUnicastLocatorList, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::META_MULTI_LOC_LIST) == 0) {
            // metatrafficMulticastLocatorList
            if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux0, builtin.metatrafficMulticastLocatorList, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::INIT_PEERS_LIST) == 0) {
            // initialPeersList
            if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux0, builtin.initialPeersList, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::READER_HIST_MEM_POLICY) == 0) {
            // readerhistoryMemoryPolicy
            if (XMLP_ret::XML_OK != getXMLHistoryMemoryPolicy(p_aux0, builtin.readerHistoryMemoryPolicy, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::WRITER_HIST_MEM_POLICY) == 0) {
            // writerhistoryMemoryPolicy
            if (XMLP_ret::XML_OK != getXMLHistoryMemoryPolicy(p_aux0, builtin.writerHistoryMemoryPolicy, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::READER_PAYLOAD_SIZE) == 0) {
            // readerPayloadSize
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &builtin.readerPayloadSize, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::WRITER_PAYLOAD_SIZE) == 0) {
            // readerPayloadSize
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &builtin.writerPayloadSize, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::MUTATION_TRIES) == 0) {
            // mutation_tries - uint32Type
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &builtin.mutation_tries, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::AVOID_BUILTIN_MULTICAST) == 0) {
            // avoid_builtin_multicast - boolType
            if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &builtin.avoid_builtin_multicast, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::USE_CLIENT) == 0) {
            if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &builtin.lookup_config.use_client, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::USE_SERVER) == 0) {
            if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &builtin.lookup_config.use_server, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'builtinAttributesType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }

    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLInitialAnnouncementsConfig(tinyxml2::XMLElement* elem, InitialAnnouncementConfig& config,
                                                         uint8_t ident) {
    /*
        <xs:complexType name="initialAnnouncementsType">
            <xs:all minOccurs="0">
                <xs:element name="count" type="uint32Type" minOccurs="0"/>
                <xs:element name="period" type="durationType" minOccurs="0"/>
            </xs:all>
        </xs:complexType>
     */
    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::COUNT) == 0) {
            // portBase - uint16Type
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &config.count, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::PERIOD) == 0) {
            // domainIDGain - uint16Type
            if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, config.period, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'portType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }
    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLPortParameters(tinyxml2::XMLElement* elem, PortParameters& port, uint8_t ident) {
    /*
        <xs:complexType name="portType">
            <xs:all minOccurs="0">
                <xs:element name="portBase" type="uint16Type" minOccurs="0"/>
                <xs:element name="domainIDGain" type="uint16Type" minOccurs="0"/>
                <xs:element name="participantIDGain" type="uint16Type" minOccurs="0"/>
                <xs:element name="offsetd0" type="uint16Type" minOccurs="0"/>
                <xs:element name="offsetd1" type="uint16Type" minOccurs="0"/>
                <xs:element name="offsetd2" type="uint16Type" minOccurs="0"/>
                <xs:element name="offsetd3" type="uint16Type" minOccurs="0"/>
            </xs:all>
        </xs:complexType>
     */

    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::PORT_BASE) == 0) {
            // portBase - uint16Type
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port.portBase, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::DOMAIN_ID_GAIN) == 0) {
            // domainIDGain - uint16Type
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port.domainIDGain, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::PARTICIPANT_ID_GAIN) == 0) {
            // participantIDGain - uint16Type
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port.participantIDGain, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::OFFSETD0) == 0) {
            // offsetd0 - uint16Type
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port.offsetd0, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::OFFSETD1) == 0) {
            // offsetd1 - uint16Type
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port.offsetd1, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::OFFSETD2) == 0) {
            // offsetd2 - uint16Type
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port.offsetd2, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::OFFSETD3) == 0) {
            // offsetd3 - uint16Type
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port.offsetd3, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'portType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }
    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLTopicAttributes(tinyxml2::XMLElement* elem, TopicAttributes& topic, uint8_t ident) {

    TopicQos& qos = topic.qos;
    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::KIND) == 0) {

            const char* text = p_aux0->GetText();
            if (nullptr == text) {
                elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "Node '" << xmlString::KIND << "' without content");
                return XMLP_ret::XML_ERROR;
            }
            if (strcmp(text, xmlString::_NO_KEY) == 0) {
                topic.topicKind = TopicKind_t::NO_KEY;
            } else if (strcmp(text, xmlString::_WITH_KEY) == 0) {
                topic.topicKind = TopicKind_t::WITH_KEY;
            } else {
                elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                          "Node '" << xmlString::KIND << "' with bad content");
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::NAME) == 0) {
            const char* text;
            if (nullptr == (text = p_aux0->GetText())) {
                elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "<" << p_aux0->Value() << "> getXMLString XML_ERROR!");
                return XMLP_ret::XML_ERROR;
            }
            topic.topicName = text;
        } else if (strcmp(name, xmlString::DATA_TYPE) == 0) {
            const char* text;
            if (nullptr == (text = p_aux0->GetText())) {
                elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "<" << p_aux0->Value() << "> getXMLString XML_ERROR!");
                return XMLP_ret::XML_ERROR;
            }
            topic.topicDataType = text;
        } else if (strcmp(name, xmlString::HISTORY_QOS) == 0) {
            HistoryQosPolicy historyQos;
            if (XMLP_ret::XML_OK != getXMLHistoryQosPolicy(p_aux0, historyQos, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            qos.history(historyQos);
            qos.history_from_xml(true);
        } else if (strcmp(name, xmlString::RES_LIMITS_QOS) == 0) {
            ResourceLimitsQosPolicy resourceLimitsQos;
            if (XMLP_ret::XML_OK != getXMLResourceLimitsQos(p_aux0, resourceLimitsQos, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            qos.resource_limits(resourceLimitsQos);
            qos.resource_from_xml(true);
        } else if (strcmp(name, xmlString::RELIABILITY) == 0) {
            ReliabilityQosPolicy reliability;
            if (XMLP_ret::XML_OK != getXMLReliabilityQos(p_aux0, reliability, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            qos.reliability(reliability);
            qos.reliability_from_xml(true);
        } else if (strcmp(name, xmlString::DURABILITY) == 0) {
            DurabilityQosPolicy durability;
            if (XMLP_ret::XML_OK != getXMLDurabilityQos(p_aux0, durability, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            qos.durability(durability);
            qos.durability_from_xml(true);
        } else if (strcmp(name, xmlString::DEADLINE) == 0) {
            DeadlineQosPolicy deadline;
            if (XMLP_ret::XML_OK != getXMLDeadlineQos(p_aux0, deadline, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            qos.deadline(deadline);
            qos.deadline_from_xml(true);
        } else if (strcmp(name, xmlString::LIFESPAN) == 0) {
            LifespanQosPolicy lifespan;
            if (XMLP_ret::XML_OK != getXMLLifespanQos(p_aux0, lifespan, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            qos.lifespan(lifespan);
            qos.lifespan_from_xml(true);
        } else if (strcmp(name, xmlString::OWNERSHIP) == 0) {
            OwnershipQosPolicy ownership;
            if (XMLP_ret::XML_OK != getXMLOwnershipQos(p_aux0, ownership, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            qos.ownership(ownership);
            qos.ownership_from_xml(true);
        } else if (strcmp(name, xmlString::SEND_MULTI) == 0) {
            qos.send_multi(false);
            std::string auxBool = p_aux0->GetText();
            if (std::strcmp(auxBool.c_str(), "TRUE") == 0 || std::strcmp(auxBool.c_str(), "true") == 0) {
                qos.send_multi(true);
            }
            qos.send_multi_from_xml(true);
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'topicAttributesType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }
    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLResourceLimitsQos(tinyxml2::XMLElement* elem, ResourceLimitsQosPolicy& resourceLimitsQos,
                                                uint8_t ident) {

    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::MAX_SAMPLES) == 0) {
            // max_samples - int32Type
            if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &resourceLimitsQos.max_samples, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::MAX_INSTANCES) == 0) {
            // max_instances - int32Type
            if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &resourceLimitsQos.max_instances, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::MAX_SAMPLES_INSTANCE) == 0) {
            // max_samples_per_instance - int32Type
            if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &resourceLimitsQos.max_samples_per_instance, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::ALLOCATED_SAMPLES) == 0) {
            // allocated_samples - int32Type
            if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &resourceLimitsQos.allocated_samples, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::EXTRA_SAMPLES) == 0) {
            // extra_samples - int32Type
            if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &resourceLimitsQos.extra_samples, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'resourceLimitsQosPolicyType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }

    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLContainerAllocationConfig(tinyxml2::XMLElement* elem,
                                                        ResourceLimitedContainerConfig& allocation_config,
                                                        uint8_t ident) {

    // First set default values
    allocation_config = ResourceLimitedContainerConfig();

    // Then parse XML
    uint32_t aux_value;
    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::INITIAL) == 0) {
            // initial - uint32Type
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &aux_value, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            allocation_config.initial = static_cast<size_t>(aux_value);
        } else if (strcmp(name, xmlString::MAXIMUM) == 0) {
            // maximum - uint32Type
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &aux_value, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            allocation_config.maximum =
                (aux_value == 0u) ? std::numeric_limits<size_t>::max() : static_cast<size_t>(aux_value);
        } else if (strcmp(name, xmlString::INCREMENT) == 0) {
            // increment - uint32Type
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &aux_value, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            allocation_config.increment = static_cast<size_t>(aux_value);
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'containerAllocationConfigType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }

    // Check results
    if (allocation_config.initial > allocation_config.maximum) {
        elogError(XMLPARSER, RetCode_t::RETCODE_OUT_OF_RESOURCES,
                  "Parsing 'containerAllocationConfigType': Field 'initial' cannot be "
                  "greater than 'maximum'.");
        return XMLP_ret::XML_ERROR;
    } else if ((allocation_config.increment == 0) && (allocation_config.initial != allocation_config.maximum)) {
        elogError(XMLPARSER, RetCode_t::RETCODE_ILLEGAL_OPERATION,
                  "Parsing 'containerAllocationConfigType': Field 'increment' cannot be zero.");
        return XMLP_ret::XML_ERROR;
    }

    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLHistoryQosPolicy(tinyxml2::XMLElement* elem, HistoryQosPolicy& historyQos,
                                               uint8_t ident) {

    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::KIND) == 0) {
            const char* text = p_aux0->GetText();
            if (nullptr == text) {
                elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "Node '" << xmlString::KIND << "' without content");
                return XMLP_ret::XML_ERROR;
            }
            if (strcmp(text, xmlString::KEEP_LAST) == 0) {
                historyQos.kind = HistoryQosPolicyKind::KEEP_LAST_HISTORY_QOS;
            } else if (strcmp(text, xmlString::KEEP_ALL) == 0) {
                historyQos.kind = HistoryQosPolicyKind::KEEP_ALL_HISTORY_QOS;
            } else {
                elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                          "Node '" << xmlString::KIND << "' with bad content");
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::DEPTH) == 0) {
            // depth - uint32Type
            if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &historyQos.depth, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'historyQosPolicyType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }

    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLDurabilityQos(tinyxml2::XMLElement* elem, DurabilityQosPolicy& durability,
                                            uint8_t /*ident*/) {

    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;
    bool bKindDefined = false;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::KIND) == 0) {
            const char* text = p_aux0->GetText();
            if (nullptr == text) {
                elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "Node '" << xmlString::KIND << "' without content");
                return XMLP_ret::XML_ERROR;
            }
            bKindDefined = true;
            if (strcmp(text, xmlString::_VOLATILE) == 0) {
                durability.kind = DurabilityQosPolicyKind::VOLATILE_DURABILITY_QOS;
            } else if (strcmp(text, xmlString::_TRANSIENT_LOCAL) == 0) {
                durability.kind = DurabilityQosPolicyKind::TRANSIENT_LOCAL_DURABILITY_QOS;
            } else if (strcmp(text, xmlString::_TRANSIENT) == 0) {
                durability.kind = DurabilityQosPolicyKind::TRANSIENT_DURABILITY_QOS;
            } else if (strcmp(text, xmlString::_PERSISTENT) == 0) {
                durability.kind = DurabilityQosPolicyKind::PERSISTENT_DURABILITY_QOS;
            } else {
                elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                          "Node '" << xmlString::KIND << "' with bad content");
                return XMLP_ret::XML_ERROR;
            }
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'durabilityQosPolicyType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }
    if (!bKindDefined) {
        elogError(XMLPARSER, RetCode_t::RETCODE_NOT_ENABLED, "Node 'durabilityQosPolicyType' without content");
        return XMLP_ret::XML_ERROR;
    }

    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLDeadlineQos(tinyxml2::XMLElement* elem, DeadlineQosPolicy& deadline, uint8_t ident) {

    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;
    bool bPeriodDefined = false;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::PERIOD) == 0) {
            bPeriodDefined = true;
            if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, deadline.period, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'deadlineQosPolicyType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }

    if (!bPeriodDefined) {
        elogError(XMLPARSER, RetCode_t::RETCODE_NOT_ENABLED, "Node 'deadlineQosPolicyType' without content");
        return XMLP_ret::XML_ERROR;
    }

    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLLivelinessQos(tinyxml2::XMLElement* elem, LivelinessQosPolicy& liveliness,
                                            uint8_t ident) {

    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::KIND) == 0) {
            // kind
            if (XMLP_ret::XML_OK != getXMLLivelinessKind(p_aux0, liveliness.kind, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::LEASE_DURATION) == 0) {
            // lease_duration
            if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, liveliness.lease_duration, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::ANNOUNCE_PERIOD) == 0) {
            // announcement_period
            if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, liveliness.announcement_period, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'livelinessQosPolicyType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }

    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLReliabilityQos(tinyxml2::XMLElement* elem, ReliabilityQosPolicy& reliability,
                                             uint8_t ident) {

    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::KIND) == 0) {
            const char* text = p_aux0->GetText();
            if (nullptr == text) {
                elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "Node '" << xmlString::KIND << "' without content");
                return XMLP_ret::XML_ERROR;
            }
            if (strcmp(text, xmlString::_BEST_EFFORT) == 0) {
                reliability.kind = ReliabilityQosPolicyKind::BEST_EFFORT_RELIABILITY_QOS;
            } else if (strcmp(text, xmlString::_RELIABLE) == 0) {
                reliability.kind = ReliabilityQosPolicyKind::RELIABLE_RELIABILITY_QOS;
            } else {
                elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                          "Node '" << xmlString::KIND << "' with bad content");
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::MAX_BLOCK_TIME) == 0) {
            // max_blocking_time
            if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, reliability.max_blocking_time, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'reliabilityQosPolicyType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }
    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLLifespanQos(tinyxml2::XMLElement* elem, LifespanQosPolicy& lifespan, uint8_t ident) {

    tinyxml2::XMLElement* p_aux0 = nullptr;
    bool bDurationDefined = false;
    const char* name = nullptr;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::DURATION) == 0) {
            bDurationDefined = true;
            if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, lifespan.duration, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'lifespanQosPolicyType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }

    if (!bDurationDefined) {
        elogError(XMLPARSER, RetCode_t::RETCODE_NOT_ENABLED, "Node 'lifespanQosPolicyType' without content");
        return XMLP_ret::XML_ERROR;
    }

    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLDisablePositiveAcksQos(tinyxml2::XMLElement* elem,
                                                     DisablePositiveACKsQosPolicy& disablePositiveAcks, uint8_t ident) {

    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::ENABLED) == 0) {
            if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &disablePositiveAcks.enabled, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::DURATION) == 0) {
            if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, disablePositiveAcks.duration, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Node 'disablePositiveAcksQosPolicyType' with unknown content");
            return XMLP_ret::XML_ERROR;
        }
    }

    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLOwnershipQos(tinyxml2::XMLElement* elem, OwnershipQosPolicy& ownership, uint8_t ident) {
    (void)ident;

    tinyxml2::XMLElement* p_aux0 = nullptr;
    bool bKindDefined = false;
    const char* name = nullptr;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::KIND) == 0) {
            bKindDefined = true;
            const char* text = p_aux0->GetText();
            if (nullptr == text) {
                elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "Node '" << xmlString::KIND << "' without content");
                return XMLP_ret::XML_ERROR;
            }
            if (strcmp(text, xmlString::SHARED) == 0) {
                ownership.kind = OwnershipQosPolicyKind::SHARED_OWNERSHIP_QOS;
            } else if (strcmp(text, xmlString::EXCLUSIVE) == 0) {
                ownership.kind = OwnershipQosPolicyKind::EXCLUSIVE_OWNERSHIP_QOS;
            } else {
                elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                          "Node '" << xmlString::KIND << "' with bad content");
                return XMLP_ret::XML_ERROR;
            }
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'ownershipQosPolicyType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }

    if (!bKindDefined) {
        elogError(XMLPARSER, RetCode_t::RETCODE_NOT_ENABLED, "Node 'ownershipQosPolicyType' without content");
        return XMLP_ret::XML_ERROR;
    }

    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLOwnershipStrengthQos(tinyxml2::XMLElement* elem,
                                                   OwnershipStrengthQosPolicy& ownershipStrength, uint8_t ident) {

    tinyxml2::XMLElement* p_aux0 = nullptr;
    bool bValueDefined = false;
    const char* name = nullptr;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::VALUE) == 0) {
            bValueDefined = true;
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &ownershipStrength.value, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'ownershipStrengthQosPolicyType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }

    if (!bValueDefined) {
        elogError(XMLPARSER, RetCode_t::RETCODE_NOT_ENABLED, "Node 'ownershipStrengthQosPolicyType' without content");
        return XMLP_ret::XML_ERROR;
    }

    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLDestinationOrderQos(tinyxml2::XMLElement* elem,
                                                  DestinationOrderQosPolicy& destinationOrder) {
    tinyxml2::XMLElement* p_aux0 = nullptr;
    bool bKindDefined = false;
    const char* name = nullptr;

    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::KIND) == 0) {
            bKindDefined = true;
            const char* text = p_aux0->GetText();
            if (nullptr == text) {
                elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "Node '" << xmlString::KIND << "' without content");
                return XMLP_ret::XML_ERROR;
            }
            if (strcmp(text, xmlString::BY_RECEPTION_TIMESTAMP) == 0) {
                destinationOrder.kind = DestinationOrderQosPolicyKind::BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS;
            } else if (strcmp(text, xmlString::BY_SOURCE_TIMESTAMP) == 0) {
                destinationOrder.kind = DestinationOrderQosPolicyKind::BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS;
            } else {
                elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER, "Node '" << xmlString::KIND << "' bad content");
                return XMLP_ret::XML_ERROR;
            }
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'destinationOrderQosPolicyType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }
    if (!bKindDefined) {
        elogError(XMLPARSER, RetCode_t::RETCODE_NOT_ENABLED, "Node 'destinationOrderQosPolicyType' without content");
        return XMLP_ret::XML_ERROR;
    }
    return XMLP_ret::XML_OK;
}

#ifdef BATCH_SEND_ENABLE
XMLP_ret XMLParserpart::getXMLBatchQos(tinyxml2::XMLElement* elem, BatchQosPolicy& batch, uint8_t ident) {
    tinyxml2::XMLElement* p_aux0 = nullptr;
    bool bValueDefined = false;
    const char* name = nullptr;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::ENABLE) == 0) {
            bValueDefined = true;
            if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &batch.enable, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::MAX_DATA_BYTES) == 0) {
            bValueDefined = true;
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &batch.max_data_bytes, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::MAX_FLUSH_DELAY) == 0) {
            bValueDefined = true;
            if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, batch.max_flush_delay, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::MAX_SAMPLES) == 0) {
            bValueDefined = true;
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &batch.max_samples, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_ERROR,
                      "Invalid element found into 'BatchQosPolicyPolicyType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }

    if (!bValueDefined) {
        elogError(XMLPARSER, RetCode_t::RETCODE_ERROR, "Node 'BatchQosPolicyType' without content");
        return XMLP_ret::XML_ERROR;
    }
    return XMLP_ret::XML_OK;
}
#endif

XMLP_ret XMLParserpart::getXMLPartitionQos(tinyxml2::XMLElement* elem, PartitionQosPolicy& partition, uint8_t ident) {

    tinyxml2::XMLElement *p_aux0 = nullptr, *p_aux1 = nullptr;
    bool bNamesDefined = false;
    const char* name = nullptr;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::NAMES) == 0) {
            bNamesDefined = true;
            p_aux1 = p_aux0->FirstChildElement(xmlString::NAME);
            if (nullptr == p_aux1) {
                // Not even one
                elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "Node '" << xmlString::NAMES << "' without content");
                return XMLP_ret::XML_ERROR;
            }

            std::vector<std::string> names;
            while (nullptr != p_aux1) {
                std::string sName = "";
                if (XMLP_ret::XML_OK != getXMLString(p_aux1, &sName, ident)) {
                    return XMLP_ret::XML_ERROR;
                }
                names.push_back(std::move(sName));
                p_aux1 = p_aux1->NextSiblingElement(xmlString::NAME);
            }
            partition.names(names);
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'partitionQosPolicyType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }

    if (!bNamesDefined) {
        elogError(XMLPARSER, RetCode_t::RETCODE_NOT_ENABLED, "Node 'partitionQosPolicyType' without content");
        return XMLP_ret::XML_ERROR;
    }

    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLLivelinessKind(tinyxml2::XMLElement* elem, LivelinessQosPolicyKind& kind,
                                             uint8_t /*ident*/) {
    const char* text = elem->GetText();
    if (nullptr == text) {
        elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "Node '" << xmlString::KIND << "' without content");
        return XMLP_ret::XML_ERROR;
    }
    if (strcmp(text, xmlString::AUTOMATIC) == 0) {
        kind = LivelinessQosPolicyKind::AUTOMATIC_LIVELINESS_QOS;
    } else if (strcmp(text, xmlString::MANUAL_BY_PARTICIPANT) == 0) {
        kind = LivelinessQosPolicyKind::MANUAL_BY_PARTICIPANT_LIVELINESS_QOS;
    } else if (strcmp(text, xmlString::MANUAL_BY_TOPIC) == 0) {
        kind = LivelinessQosPolicyKind::MANUAL_BY_TOPIC_LIVELINESS_QOS;
    } else {
        elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER, "Node '" << xmlString::KIND << "' with bad content");
        return XMLP_ret::XML_ERROR;
    }
    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLPublishModeQos(tinyxml2::XMLElement* elem, PublishModeQosPolicy& publishMode,
                                             uint8_t /*ident*/) {

    tinyxml2::XMLElement* p_aux0 = nullptr;
    bool bKindDefined = false;
    const char* name = nullptr;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::KIND) == 0) {

            bKindDefined = true;
            const char* text = p_aux0->GetText();
            if (nullptr == text) {
                elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "Node '" << xmlString::KIND << "' without content");
                return XMLP_ret::XML_ERROR;
            }
            if (strcmp(text, xmlString::SYNCHRONOUS) == 0) {
                publishMode.kind = PublishModeQosPolicyKind::SYNCHRONOUS_PUBLISH_MODE;
            } else if (strcmp(text, xmlString::ASYNCHRONOUS) == 0) {
                publishMode.kind = PublishModeQosPolicyKind::ASYNCHRONOUS_PUBLISH_MODE;
            } else {
                elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER, "Node '" << xmlString::KIND << "' bad content");
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::FLOW_CONTROLLER_NAME) == 0) {

            const char* text = p_aux0->GetText();
            if ((nullptr != text) && (publishMode.kind == PublishModeQosPolicyKind::ASYNCHRONOUS_PUBLISH_MODE)) {
                publishMode.flowname = text;
                publishMode.flow_controller_name = publishMode.flowname.c_str();
            } else {
                elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                          "Node '" << xmlString::FLOW_CONTROLLER_NAME << "' bad content");
                return XMLP_ret::XML_ERROR;
            }
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'publishModeQosPolicyType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }

    if (!bKindDefined) {
        elogError(XMLPARSER, RetCode_t::RETCODE_NOT_ENABLED, "Node 'publishModeQosPolicyType' without content");
        return XMLP_ret::XML_ERROR;
    }

    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLDuration(tinyxml2::XMLElement* elem, Duration_t& duration, uint8_t ident) {

    // set default values
    duration.seconds = 0;
    duration.nanosec = 0;

    // it's mandatory to provide a sec or nanocsec child item
    bool empty = true;

    try {
        // First we check if it matches the schema pattern
        std::regex infinite(xmlString::DURATION_INFINITY);
        std::regex infinite_sec(xmlString::DURATION_INFINITE_SEC);
        std::regex infinite_nsec(xmlString::DURATION_INFINITE_NSEC);
        const char* text = elem->GetText();

        if ((text != nullptr) && std::regex_match(text, infinite)) {
            empty = false;
            duration = c_TimeInfinite;

            if (elem->FirstChildElement() != nullptr) {
                elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                          "If a Duration_t type element is defined as DURATION_INFINITY it "
                          "cannot have <sec> or"
                          " <nanosec> subelements.");
                return XMLP_ret::XML_ERROR;
            }
        }

        tinyxml2::XMLElement* p_aux0 = nullptr;
        const char* name = nullptr;
        for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
            // there is at least a child element
            empty = false;

            name = p_aux0->Name();
            if (strcmp(name, xmlString::SECONDS) == 0) {
                text = p_aux0->GetText();
                if (nullptr == text) {
                    elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "Node 'SECONDS' without content");
                    return XMLP_ret::XML_ERROR;
                } else if (std::regex_match(text, infinite_sec)) {
                    // if either SECONDS or NANOSECONDS is set to infinity then all of it is
                    duration = c_TimeInfinite;
                    return XMLP_ret::XML_OK;
                } else if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &duration.seconds, ident)) {
                    elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                              "<" << elem->Value() << "> getXMLInt XML_ERROR!");
                    return XMLP_ret::XML_ERROR;
                }
            } else if (strcmp(name, xmlString::NANOSECONDS) == 0) {
                text = p_aux0->GetText();
                if (nullptr == text) {
                    elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "Node 'NANOSECONDS' without content");
                    return XMLP_ret::XML_ERROR;
                } else if (std::regex_match(text, infinite_nsec)) {
                    // if either SECONDS or NANOSECONDS is set to infinity then all of it is
                    duration = c_TimeInfinite;
                    return XMLP_ret::XML_OK;
                } else if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &duration.nanosec, ident)) {
                    elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                              "<" << elem->Value() << "> getXMLInt XML_ERROR!");
                    return XMLP_ret::XML_ERROR;
                }
            } else {
                elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                          "Invalid element found into 'durationType'. Name: " << name);
                return XMLP_ret::XML_ERROR;
            }
        }
    } catch (std::regex_error& e) {
        elogError(XMLPARSER, RetCode_t::RETCODE_ILLEGAL_OPERATION,
                  "getXMLDuration Caught std::regex_error exception: " << e.what());
        return XMLP_ret::XML_ERROR;
    } catch (std::exception& e) {
        elogError(XMLPARSER, RetCode_t::RETCODE_ILLEGAL_OPERATION, "getXMLDuration caught: " << e.what());
        return XMLP_ret::XML_ERROR;
    }

    // An empty Duration_t xml is forbidden
    if (empty) {
        elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA,
                  "'durationType' elements cannot be empty."
                  "At least second or nanoseconds should be provided");
        return XMLP_ret::XML_ERROR;
    }

    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLWriterTimes(tinyxml2::XMLElement* elem, WriterTimes& times, uint8_t ident) {

    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::INIT_HEARTB_DELAY) == 0) {
            // initialHeartbeatDelay
            if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, times.initialHeartbeatDelay, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::HEARTB_PERIOD) == 0) {
            // heartbeatPeriod
            if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, times.heartbeatPeriod, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::NACK_RESP_DELAY) == 0) {
            // nackResponseDelay
            if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, times.nackResponseDelay, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::NACK_SUPRESSION) == 0) {
            // nackSupressionDuration
            if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, times.nackSupressionDuration, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::FAST_HEARTB_PERIOD) == 0) {
            // heartbeatPeriod
            if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, times.fastHeartbeatPeriod, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'writerTimesType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }

    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLReaderTimes(tinyxml2::XMLElement* elem, ReaderTimes& times, uint8_t ident) {

    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::INIT_ACKNACK_DELAY) == 0) {
            // initialAcknackDelay
            if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, times.initialAcknackDelay, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::HEARTB_RESP_DELAY) == 0) {
            // heartbeatResponseDelay
            if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, times.heartbeatResponseDelay, ident)) {
                return XMLP_ret::XML_ERROR;
            }
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'readerTimesType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }

    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLLocatorUDPv4(tinyxml2::XMLElement* elem, xmlparser::Locator_t& locator, uint8_t ident) {

    std::unordered_map<std::string, bool> tags_present;
    locator.kind = LOCATOR_KIND_UDPv4;
    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (tags_present[name]) {
            elogError(XMLPARSER, RetCode_t::RETCODE_ILLEGAL_OPERATION,
                      "Duplicated element found in 'udpv4LocatorType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
        tags_present[name] = true;

        if (strcmp(name, xmlString::PORT) == 0) {
            // port - uint32Type
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &locator.port, ident + 1)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::ADDRESS) == 0) {
            // address - stringType
            std::string s = "";
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &s, ident + 1)) {
                return XMLP_ret::XML_ERROR;
            }
            // Check whether the address is IPv4
            if (!IPLocator::isIPv4(s)) {
                try {
                    auto response = xmlparser::IPLocator::resolveNameDNS(s);
                    // Add the first valid IPv4 address that we can find
                    if (response.first.size() > 0) {
                        s = response.first.begin()->data();
                    } else {
                        elogError(XMLPARSER, RetCode_t::RETCODE_OUT_OF_RESOURCES,
                                  "DNS server did not return any IPv4 address for: '" << s << "'. Name: " << name);
                        return XMLP_ret::XML_ERROR;
                    }
                } catch (const asio::invalid_service_owner& e) {
                    elogError(XMLPARSER, RetCode_t::RETCODE_ILLEGAL_OPERATION,
                              "parseXMLReplierProf() Caught asio::invalid_service_owner exception: " << e.what());
                    return XMLP_ret::XML_ERROR;
                } catch (const asio::system_error& e) {
                    elogError(XMLPARSER, RetCode_t::RETCODE_ILLEGAL_OPERATION,
                              "parseXMLReplierProf() catch system_error: " << e.what());
                    return XMLP_ret::XML_ERROR;
                } catch (const asio::service_already_exists& e) {
                    elogError(XMLPARSER, RetCode_t::RETCODE_ILLEGAL_OPERATION,
                              "parseXMLReplierProf() catch asio::service_already_exists: " << e.what());
                    return XMLP_ret::XML_ERROR;
                } catch (const std::exception& e) {
                    elogError(XMLPARSER, RetCode_t::RETCODE_ILLEGAL_OPERATION,
                              "parseXMLReplierProf() catch other error: " << e.what());
                    return XMLP_ret::XML_ERROR;
                }
            }
            (void)IPLocator::setIPv4(locator, s);
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'udpv4LocatorType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }
    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLLocatorUDS(tinyxml2::XMLElement* elem, xmlparser::Locator_t& locator, uint8_t ident) {

    std::unordered_map<std::string, bool> tags_present;
    locator.kind = LOCATOR_KIND_UDS;
    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (tags_present[name]) {
            elogError(XMLPARSER, RetCode_t::RETCODE_ILLEGAL_OPERATION,
                      "Duplicated element found in 'udsLocatorType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
        tags_present[name] = true;

        if (strcmp(name, xmlString::ADDRESS) == 0) {
            // address - stringType
            std::string s = "";
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &s, ident + 1)) {
                return XMLP_ret::XML_ERROR;
            }
            // Check whether the address size
            if (s.size() >= 16) {
                elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                          "Error: Input string is too long to be stored in the address array.");
                return XMLP_ret::XML_ERROR;
            }

            std::strncpy(reinterpret_cast<char*>(locator.address), s.c_str(), s.size());
            locator.address[s.size()] = '\0';
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'udsLocatorType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }
    return XMLP_ret::XML_OK;
}

#ifdef VBS_IPV6
XMLP_ret XMLParserpart::getXMLLocatorUDPv6(tinyxml2::XMLElement* elem, xmlparser::Locator_t& locator, uint8_t ident) {

    std::unordered_map<std::string, bool> tags_present;

    locator.kind = LOCATOR_KIND_UDPv6;
    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (tags_present[name]) {
            elogError(XMLPARSER, RetCode_t::RETCODE_ERROR,
                      "Duplicated element found in 'udpv6LocatorType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
        tags_present[name] = true;

        if (strcmp(name, xmlString::PORT) == 0) {
            // port - uint32Type
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &locator.port, ident + 1)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::ADDRESS) == 0) {
            // address - stringType
            std::string s = "";
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &s, ident + 1)) {
                return XMLP_ret::XML_ERROR;
            }
            // Check whether the address is IPv6
            if (!IPLocator::isIPv6(s)) {
                try {
                    auto response = xmlparser::IPLocator::resolveNameDNS(s);

                    // Add the first valid IPv6 address that we can find
                    if (response.second.size() > 0) {
                        s = response.second.begin()->data();
                    } else {
                        elogError(XMLPARSER, RetCode_t::RETCODE_ERROR,
                                  "DNS server did not return any IPv6 address for: '" << s << "'. Name: " << name);
                        return XMLP_ret::XML_ERROR;
                    }
                } catch (const asio::invalid_service_owner& e) {
                    elogError(XMLPARSER, RetCode_t::RETCODE_ERROR,
                              "parseXMLReplierProf() Caught asio::invalid_service_owner exception: " << e.what());
                    return XMLP_ret::XML_ERROR;
                } catch (const asio::system_error& e) {
                    elogError(XMLPARSER, RetCode_t::RETCODE_ERROR,
                              "parseXMLReplierProf() catch system_error: " << e.what());
                    return XMLP_ret::XML_ERROR;
                } catch (const asio::service_already_exists& e) {
                    elogError(XMLPARSER, RetCode_t::RETCODE_ERROR,
                              "parseXMLReplierProf() catch asio::service_already_exists: " << e.what());
                    return XMLP_ret::XML_ERROR;
                } catch (const std::exception& e) {
                    elogError(XMLPARSER, RetCode_t::RETCODE_ERROR,
                              "parseXMLReplierProf() catch other error: " << e.what());
                    return XMLP_ret::XML_ERROR;
                }
            }
            (void)IPLocator::setIPv6(locator, s);
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_ERROR,
                      "Invalid element found into 'udpv6LocatorType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }
    return XMLP_ret::XML_OK;
}
#endif
XMLP_ret XMLParserpart::getXMLLocatorTCPv4(tinyxml2::XMLElement* elem, xmlparser::Locator_t& locator, uint8_t ident) {

    std::unordered_map<std::string, bool> tags_present;

    locator.kind = LOCATOR_KIND_TCPv4;
    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (tags_present[name]) {
            elogError(XMLPARSER, RetCode_t::RETCODE_ILLEGAL_OPERATION,
                      "Duplicated element found in 'tcpv4LocatorType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
        tags_present[name] = true;

        if (strcmp(name, xmlString::PORT) == 0) {
            // port - uint16Type
            uint16_t port(0);
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port, ident + 1)) {
                return XMLP_ret::XML_ERROR;
            }
            (void)IPLocator::setLogicalPort(locator, port);
        } else if (strcmp(name, xmlString::PHYSICAL_PORT) == 0) {
            // physical_port - uint16Type
            uint16_t port(0);
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port, ident + 1)) {
                return XMLP_ret::XML_ERROR;
            }
            (void)IPLocator::setPhysicalPort(locator, port);
        } else if (strcmp(name, xmlString::ADDRESS) == 0) {
            // address - stringType
            std::string s = "";
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &s, ident + 1)) {
                return XMLP_ret::XML_ERROR;
            }
            (void)IPLocator::setIPv4(locator, s);
        } else if (strcmp(name, xmlString::WAN_ADDRESS) == 0) {
            // address - stringType
            std::string s = "";
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &s, ident + 1)) {
                return XMLP_ret::XML_ERROR;
            }
            (void)IPLocator::setWan(locator, s);
        } else if (strcmp(name, xmlString::UNIQUE_LAN_ID) == 0) {
            // address - stringType
            std::string s = "";
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &s, ident + 1)) {
                return XMLP_ret::XML_ERROR;
            }
            (void)IPLocator::setLanID(locator, s);
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'tcpv4LocatorType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }
    return XMLP_ret::XML_OK;
}
#ifdef VBS_IPV6
XMLP_ret XMLParserpart::getXMLLocatorTCPv6(tinyxml2::XMLElement* elem, xmlparser::Locator_t& locator, uint8_t ident) {

    std::unordered_map<std::string, bool> tags_present;

    locator.kind = LOCATOR_KIND_TCPv6;
    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (tags_present[name]) {
            elogError(XMLPARSER, RetCode_t::RETCODE_ERROR,
                      "Duplicated element found in 'tcpv6LocatorType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
        tags_present[name] = true;

        if (strcmp(name, xmlString::PORT) == 0) {
            // port - uint16Type
            uint16_t port(0);
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port, ident + 1)) {
                return XMLP_ret::XML_ERROR;
            }
            (void)IPLocator::setLogicalPort(locator, port);
        } else if (strcmp(name, xmlString::PHYSICAL_PORT) == 0) {
            // physical_port - uint16Type
            uint16_t port(0);
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port, ident + 1)) {
                return XMLP_ret::XML_ERROR;
            }
            (void)IPLocator::setPhysicalPort(locator, port);
        } else if (strcmp(name, xmlString::ADDRESS) == 0) {
            // address - stringType
            std::string s = "";
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &s, ident + 1)) {
                return XMLP_ret::XML_ERROR;
            }
            (void)IPLocator::setIPv6(locator, s);
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_ERROR,
                      "Invalid element found into 'tcpv6LocatorType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }
    return XMLP_ret::XML_OK;
}
#endif

template <typename T>
static XMLP_ret process_unsigned_attribute(const tinyxml2::XMLElement* elem, const char* name, T& value,
                                           const uint32_t min_value, const uint32_t max_value) {
    auto attribute = elem->FindAttribute(name);
    if (nullptr != attribute) {
        uint32_t v = 0;
        if (tinyxml2::XMLError::XML_SUCCESS == attribute->QueryUnsignedValue(&v)) {
            if ((min_value <= v) && (v <= max_value)) {
                value = static_cast<T>(v);
                return XMLP_ret::XML_OK;
            }
        }

        elogError(
            XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
            "Wrong value '" << attribute->Value() << "' for attribute '" << name << "' on '" << elem->Name() << "'");
        return XMLP_ret::XML_ERROR;
    }

    return XMLP_ret::XML_OK;
}

static XMLP_ret process_external_locator_attributes(const tinyxml2::XMLElement* elem,
                                                    vbsutil::xmlparser::LocatorWithMask& locator,
                                                    vbsutil::xmlparser::ExternalLocators& external_locators) {
    static const char* EXTERNALITY_ATTR_NAME = "externality";
    static const char* COST_ATTR_NAME = "cost";
    static const char* MASK_ATTR_NAME = "mask";

    // Attributes initialized with default value
    uint8_t externality = 1;
    uint8_t cost = 0;
    uint8_t mask = 24;

    if ((XMLP_ret::XML_OK != process_unsigned_attribute(elem, EXTERNALITY_ATTR_NAME, externality, 1, 255)) ||
        (XMLP_ret::XML_OK != process_unsigned_attribute(elem, COST_ATTR_NAME, cost, 0, 255)) ||
        (XMLP_ret::XML_OK != process_unsigned_attribute(elem, MASK_ATTR_NAME, mask, 1, 127))) {
        return XMLP_ret::XML_ERROR;
    }

    locator.mask(mask);
    external_locators[externality][cost].push_back(locator);

    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLExternalLocatorList(tinyxml2::XMLElement* elem,
                                                  xmlparser::ExternalLocators& external_locators, uint8_t ident) {

    external_locators.clear();

    tinyxml2::XMLElement* child = nullptr;
    for (child = elem->FirstChildElement(); nullptr != child; child = child->NextSiblingElement()) {
        xmlparser::LocatorWithMask locator;
        const char* name = child->Name();
        if (strcmp(name, xmlString::UDPv4_LOCATOR) == 0) {
            if (XMLP_ret::XML_OK != getXMLLocatorUDPv4(child, locator, ident + 1)) {
                external_locators.clear();
                return XMLP_ret::XML_ERROR;
            }
        }
#ifdef VBS_IPV6
        else if (strcmp(name, xmlString::UDPv6_LOCATOR) == 0) {
            if (XMLP_ret::XML_OK != getXMLLocatorUDPv6(child, locator, ident + 1)) {
                external_locators.clear();
                return XMLP_ret::XML_ERROR;
            }
        }
#endif
        else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found inside 'externalLocatorListType'. Name: " << name);
            external_locators.clear();
            return XMLP_ret::XML_ERROR;
        }

        if (IPLocator::isAny(locator) || (0 == locator.port)) {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Address and port are mandatory for 'udpExternalLocatorType'.");
            external_locators.clear();
            return XMLP_ret::XML_ERROR;
        }

        if (IPLocator::isMulticast(locator)) {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Address should be unicast for 'udpExternalLocatorType'.");
            external_locators.clear();
            return XMLP_ret::XML_ERROR;
        }

        if (XMLP_ret::XML_OK != process_external_locator_attributes(child, locator, external_locators)) {
            external_locators.clear();
            return XMLP_ret::XML_ERROR;
        }
    }

    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLLocatorList(tinyxml2::XMLElement* elem, LocatorList_t& locatorList, uint8_t ident) {

    tinyxml2::XMLElement *p_aux0 = nullptr, *p_aux1 = nullptr;
    p_aux0 = elem->FirstChildElement(xmlString::LOCATOR);
    if (nullptr == p_aux0) {
        elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "Node '" << elem->Value() << "' without content");
        return XMLP_ret::XML_ERROR;
    }

    while (nullptr != p_aux0) {
        Locator_t loc;
        if (nullptr != (p_aux1 = p_aux0->FirstChildElement(xmlString::UDPv4_LOCATOR))) {
            if (XMLP_ret::XML_OK != getXMLLocatorUDPv4(p_aux1, loc, ident + 1)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (nullptr != (p_aux1 = p_aux0->FirstChildElement(xmlString::UDS_LOCATOR))) {
            if (XMLP_ret::XML_OK != getXMLLocatorUDS(p_aux1, loc, ident + 1)) {
                return XMLP_ret::XML_ERROR;
            }
        }
#ifdef VBS_IPV6
        else if (nullptr != (p_aux1 = p_aux0->FirstChildElement(xmlString::UDPv6_LOCATOR))) {
            if (XMLP_ret::XML_OK != getXMLLocatorUDPv6(p_aux1, loc, ident + 1)) {
                return XMLP_ret::XML_ERROR;
            }
        }
#endif
        else if (nullptr != (p_aux1 = p_aux0->FirstChildElement(xmlString::TCPv4_LOCATOR))) {
            if (XMLP_ret::XML_OK != getXMLLocatorTCPv4(p_aux1, loc, ident + 1)) {
                return XMLP_ret::XML_ERROR;
            }
        }
#ifdef VBS_IPV6
        else if (nullptr != (p_aux1 = p_aux0->FirstChildElement(xmlString::TCPv6_LOCATOR))) {
            if (XMLP_ret::XML_OK != getXMLLocatorTCPv6(p_aux1, loc, ident + 1)) {
                return XMLP_ret::XML_ERROR;
            }
        }
#endif
        else if (nullptr != (p_aux1 = p_aux0->FirstChildElement())) {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'locatorType'. Name: " << p_aux1->Name());
            return XMLP_ret::XML_ERROR;
        }

        locatorList.push_back(loc);
        p_aux0 = p_aux0->NextSiblingElement(xmlString::LOCATOR);
    }

    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLHistoryMemoryPolicy(tinyxml2::XMLElement* elem,
                                                  MemoryManagementPolicy_t& historyMemoryPolicy, uint8_t /*ident*/) {
    const char* text = elem->GetText();
    if (nullptr == text) {
        elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "Node '" << xmlString::KIND << "' without content");
        return XMLP_ret::XML_ERROR;
    }
    if (strcmp(text, xmlString::PREALLOCATED) == 0) {
        historyMemoryPolicy = MemoryManagementPolicy::PREALLOCATED_MEMORY_MODE;
    } else if (strcmp(text, xmlString::PREALLOCATED_WITH_REALLOC) == 0) {
        historyMemoryPolicy = MemoryManagementPolicy::PREALLOCATED_WITH_REALLOC_MEMORY_MODE;
    } else if (strcmp(text, xmlString::DYNAMIC) == 0) {
        historyMemoryPolicy = MemoryManagementPolicy::DYNAMIC_RESERVE_MEMORY_MODE;
    } else if (strcmp(text, xmlString::DYNAMIC_REUSABLE) == 0) {
        historyMemoryPolicy = MemoryManagementPolicy::DYNAMIC_REUSABLE_MEMORY_MODE;
    } else if (strcmp(text, xmlString::AUTOMATIC) == 0) {
        historyMemoryPolicy = MemoryManagementPolicy::AUTOMATIC_MEMORY_MODE;
    } else {
        elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER, "Node '" << xmlString::KIND << "' bad content");
        return XMLP_ret::XML_ERROR;
    }

    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLPropertiesPolicy(tinyxml2::XMLElement* elem, PropertyPolicy& propertiesPolicy,
                                               uint8_t ident) {

    tinyxml2::XMLElement *p_aux0 = nullptr, *p_aux1 = nullptr, *p_aux2 = nullptr;
    const char* name = nullptr;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != nullptr; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (strcmp(name, xmlString::PROPERTIES) == 0) {
            p_aux1 = p_aux0->FirstChildElement(xmlString::PROPERTY);
            if (nullptr == p_aux1) {
                elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA,
                          "Node '" << xmlString::PROPERTIES << "' without content");
                return XMLP_ret::XML_ERROR;
            }

            while (nullptr != p_aux1) {

                const char* sub_name = nullptr;
                Property prop;
                for (p_aux2 = p_aux1->FirstChildElement(); p_aux2 != NULL; p_aux2 = p_aux2->NextSiblingElement()) {
                    sub_name = p_aux2->Name();
                    if (strcmp(sub_name, xmlString::NAME) == 0) {
                        // name - stringType
                        std::string s = "";
                        if (XMLP_ret::XML_OK != getXMLString(p_aux2, &s, ident + 2)) {
                            return XMLP_ret::XML_ERROR;
                        }
                        prop.name(s);
                    } else if (strcmp(sub_name, xmlString::VALUE) == 0) {
                        // value - stringType
                        std::string s = "";
                        if (XMLP_ret::XML_OK != getXMLString(p_aux2, &s, ident + 2)) {
                            return XMLP_ret::XML_ERROR;
                        }
                        prop.value(s);
                    } else if (strcmp(sub_name, xmlString::PROPAGATE) == 0) {
                        // propagate - boolType
                        bool b = false;
                        if (XMLP_ret::XML_OK != getXMLBool(p_aux2, &b, ident + 2)) {
                            return XMLP_ret::XML_ERROR;
                        }
                        prop.propagate(b);
                    }
                }
                propertiesPolicy.properties().push_back(std::move(prop));
                p_aux1 = p_aux1->NextSiblingElement(xmlString::PROPERTY);
            }
        } else if (strcmp(name, xmlString::BIN_PROPERTIES) == 0) {
            // TODO(test): The value will be std::vector<uint8_t>
            p_aux1 = p_aux0->FirstChildElement(xmlString::PROPERTY);
            if (nullptr == p_aux1) {
                elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA,
                          "Node '" << xmlString::BIN_PROPERTIES << "' without content");
                return XMLP_ret::XML_ERROR;
            }

            while (nullptr != p_aux1) {
                const char* sub_name = nullptr;
                BinaryProperty bin_prop;
                for (p_aux2 = p_aux1->FirstChildElement(); p_aux2 != NULL; p_aux2 = p_aux2->NextSiblingElement()) {
                    sub_name = p_aux2->Name();
                    if (strcmp(sub_name, xmlString::NAME) == 0) {
                        // name - stringType
                        std::string s = "";
                        if (XMLP_ret::XML_OK != getXMLString(p_aux2, &s, ident + 2)) {
                            return XMLP_ret::XML_ERROR;
                        }
                        bin_prop.name(s);
                    } else if (strcmp(sub_name, xmlString::VALUE) == 0) {
                        // TODO(test):
                        // value - stringType
                        elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                                  "Tag '" << p_aux2->Value() << "' do not supported for now");
                        /*std::string s = "";
                           if (XMLP_ret::XML_OK != getXMLString(p_aux2, &s, ident + 2)) return
                           XMLP_ret::XML_ERROR; bin_prop.value(s);*/
                    } else if (strcmp(sub_name, xmlString::PROPAGATE) == 0) {
                        // propagate - boolType
                        bool b = false;
                        if (XMLP_ret::XML_OK != getXMLBool(p_aux2, &b, ident + 2)) {
                            return XMLP_ret::XML_ERROR;
                        }
                        bin_prop.propagate(b);
                    }
                }
                propertiesPolicy.binary_properties().push_back(std::move(bin_prop));
                p_aux1 = p_aux1->NextSiblingElement(xmlString::PROPERTY);
            }
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'propertyPolicyType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }
    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLFlowControllers(
    tinyxml2::XMLElement* elem, std::vector<std::shared_ptr<xmlparser::FlowControllerDescriptor>>& flowControllers,
    uint8_t ident) {
    tinyxml2::XMLElement *p_aux0 = nullptr, *p_aux1 = nullptr;
    p_aux0 = elem->FirstChildElement(xmlString::FLOW_CONTROL_DESCRIPTOR);
    if (nullptr == p_aux0) {
        elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "Node '" << elem->Value() << "' without content");
        return XMLP_ret::XML_ERROR;
    }

    while (nullptr != p_aux0) {
        const char* name = nullptr;
        std::shared_ptr<xmlparser::FlowControllerDescriptor> pflowController =
            std::make_shared<xmlparser::FlowControllerDescriptor>();

        for (p_aux1 = p_aux0->FirstChildElement(); p_aux1 != NULL; p_aux1 = p_aux1->NextSiblingElement()) {
            name = p_aux1->Name();
            if (strcmp(name, xmlString::NAME) == 0) {
                if (XMLP_ret::XML_OK != getXMLString(p_aux1, &pflowController->flowname, ident + 2)) {
                    return XMLP_ret::XML_ERROR;
                }
                pflowController->name = pflowController->flowname.c_str();
            } else if (strcmp(name, xmlString::SCHEDULE_MODE) == 0) {
                // scheduleMode
                const char* text = p_aux1->GetText();
                if (nullptr == text) {
                    elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA,
                              "Node '" << xmlString::SCHEDULE_MODE << "' without content");
                    return XMLP_ret::XML_ERROR;
                }

                if (strcmp(text, xmlString::FIFO) == 0) {
                    pflowController->scheduler = xmlparser::FlowControllerSchedulerPolicy::FIFO;
                } else if (strcmp(text, xmlString::ROUND_ROBIN) == 0) {
                    pflowController->scheduler = xmlparser::FlowControllerSchedulerPolicy::ROUND_ROBIN;
                } else if (strcmp(text, xmlString::HIGH_PRIORITY) == 0) {
                    pflowController->scheduler = xmlparser::FlowControllerSchedulerPolicy::HIGH_PRIORITY;
                } else if (strcmp(text, xmlString::PRIORITY_WITH_RESERVATION) == 0) {
                    pflowController->scheduler = xmlparser::FlowControllerSchedulerPolicy::PRIORITY_WITH_RESERVATION;
                } else {
                    elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                              "Node '" << xmlString::SCHEDULE_MODE << "' with bad content");
                    return XMLP_ret::XML_ERROR;
                }
            } else if (strcmp(name, xmlString::BYTES_PER_SECOND) == 0) {
                // bytesPerPeriod - int32Type
                if (XMLP_ret::XML_OK != getXMLInt(p_aux1, &pflowController->max_bytes_per_period, ident)) {
                    return XMLP_ret::XML_ERROR;
                }
            } else if (strcmp(name, xmlString::PERIOD_MILLISECS) == 0) {
                // periodMillisecs - uint64Type
                if (XMLP_ret::XML_OK != getXMLUint64(p_aux1, &pflowController->period_ms, ident)) {
                    return XMLP_ret::XML_ERROR;
                }
            } else {
                elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER, "Invalid element in 'flowController'");
                return XMLP_ret::XML_ERROR;
            }
        }
        flowControllers.push_back(std::move(pflowController));

        p_aux0 = p_aux0->NextSiblingElement(xmlString::FLOW_CONTROL_DESCRIPTOR);
    }

    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLOctetVector(tinyxml2::XMLElement* elem, std::vector<octet>& octet_vector,
                                          uint8_t /*ident*/) {
    if (nullptr == elem) {
        elogError(XMLPARSER, RetCode_t::RETCODE_ERROR, "preconditions error");
        return XMLP_ret::XML_ERROR;
    }

    tinyxml2::XMLElement* p_aux0 = nullptr;
    XMLP_ret ret_value = XMLP_ret::XML_OK;
    size_t num_elems = 0;

    for (p_aux0 = elem->FirstChildElement(); nullptr != p_aux0; p_aux0 = p_aux0->NextSiblingElement()) {
        if (1 < ++num_elems) {
            elogError(XMLPARSER, RetCode_t::RETCODE_OUT_OF_RESOURCES, "More than one tag on " << p_aux0->GetLineNum());
            ret_value = XMLP_ret::XML_ERROR;
        }
        if (0 == strcmp(p_aux0->Name(), xmlString::VALUE)) {
            std::string text = p_aux0->GetText();
            std::istringstream ss(text);

            ss >> std::hex;

            while (!ss.eof()) {
                uint16_t o = 0;
                ss >> o;

                if ((!ss) || (std::numeric_limits<octet>::max() < o)) {
                    elogError(XMLPARSER, RetCode_t::RETCODE_OUT_OF_RESOURCES,
                              "Expected an octet value on line " << p_aux0->GetLineNum());
                    ret_value = XMLP_ret::XML_ERROR;
                    break;
                }

                // Add octet in vector.
                octet_vector.push_back(static_cast<octet>(o));

                if (!ss.eof()) {
                    char c = 0;
                    ss >> c;

                    if (!ss || '.' != c) {
                        elogError(XMLPARSER, RetCode_t::RETCODE_OUT_OF_RESOURCES,
                                  "Expected a '.' separator on line " << p_aux0->GetLineNum());
                        ret_value = XMLP_ret::XML_ERROR;
                        break;
                    }
                }
            }
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid tag with name of " << p_aux0->Name() << " on line " << p_aux0->GetLineNum());
            ret_value = XMLP_ret::XML_ERROR;
        }
    }

    return ret_value;
}

XMLP_ret XMLParserpart::getXMLInt(tinyxml2::XMLElement* elem, int32_t* in, uint8_t /*ident*/) {
    if ((nullptr == elem) || (nullptr == in)) {
        elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "nullptr when getXMLUint XML_ERROR!");
        return XMLP_ret::XML_ERROR;
    } else if (tinyxml2::XMLError::XML_SUCCESS != elem->QueryIntText(in)) {
        elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER, "<" << elem->Value() << "> getXMLInt XML_ERROR!");
        return XMLP_ret::XML_ERROR;
    }
    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLUint(tinyxml2::XMLElement* elem, uint32_t* ui, uint8_t /*ident*/) {
    if ((nullptr == elem) || (nullptr == ui)) {
        elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "nullptr when getXMLUint XML_ERROR!");
        return XMLP_ret::XML_ERROR;
    } else if (tinyxml2::XMLError::XML_SUCCESS != elem->QueryUnsignedText(ui)) {
        elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER, "<" << elem->Value() << "> getXMLUint XML_ERROR!");
        return XMLP_ret::XML_ERROR;
    }
    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLUint(tinyxml2::XMLElement* elem, uint16_t* ui16, uint8_t /*ident*/) {
    uint32_t ui = 0u;
    if ((nullptr == elem) || (nullptr == ui16)) {
        elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "nullptr when getXMLUint XML_ERROR!");
        return XMLP_ret::XML_ERROR;
    } else if (tinyxml2::XMLError::XML_SUCCESS != elem->QueryUnsignedText(&ui) || ui >= 65536) {
        elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER, "<" << elem->Value() << "> getXMLUint XML_ERROR!");
        return XMLP_ret::XML_ERROR;
    }
    *ui16 = static_cast<uint16_t>(ui);
    return XMLP_ret::XML_OK;
}
XMLP_ret XMLParserpart::getXMLUint64(tinyxml2::XMLElement* elem, uint64_t* ui64, uint8_t /*ident*/) {
    uint64_t ui = 0u;
    if ((nullptr == elem) || (nullptr == ui64)) {
        elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "nullptr when getXMLUint XML_ERROR!");
        return XMLP_ret::XML_ERROR;
    } else if (tinyxml2::XMLError::XML_SUCCESS != elem->QueryUnsigned64Text(&ui)) {
        elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER, "<" << elem->Value() << "> getXMLUint64 XML_ERROR!");
        return XMLP_ret::XML_ERROR;
    }
    *ui64 = static_cast<uint64_t>(ui);
    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLFloat(tinyxml2::XMLElement* elem, float* fl, uint8_t /*ident*/) {
    if ((nullptr == elem) || (nullptr == fl)) {
        elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "nullptr when getXMLFloat XML_ERROR!");
        return XMLP_ret::XML_ERROR;
    } else if (tinyxml2::XMLError::XML_SUCCESS != elem->QueryFloatText(fl)) {
        elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER, "<" << elem->Value() << "> getXMLFloat XML_ERROR!");
        return XMLP_ret::XML_ERROR;
    }
    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLBool(tinyxml2::XMLElement* elem, bool* b, uint8_t /*ident*/) {
    if ((nullptr == elem) || (nullptr == b)) {
        elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "nullptr when getXMLUint XML_ERROR!");
        return XMLP_ret::XML_ERROR;
    } else if (tinyxml2::XMLError::XML_SUCCESS != elem->QueryBoolText(b)) {
        elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER, "<" << elem->Value() << "> getXMLBool XML_ERROR!");
        return XMLP_ret::XML_ERROR;
    }
    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLEnum(tinyxml2::XMLElement* elem, DiscoveryProtocol_t* e, uint8_t /*ident*/) {

    const char* text = nullptr;

    if (nullptr == elem || nullptr == e) {
        elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "nullptr when getXMLEnum XML_ERROR!");
        return XMLP_ret::XML_ERROR;
    } else if (nullptr == (text = elem->GetText())) {
        elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "<" << elem->Value() << "> getXMLEnum XML_ERROR!");
        return XMLP_ret::XML_ERROR;
    } else if (strcmp(text, xmlString::_NONE) == 0) {
        *e = DiscoveryProtocol_t::NONE;
    } else if (strcmp(text, xmlString::_SIMPLE) == 0) {
        *e = DiscoveryProtocol_t::SIMPLE;
    } else if (strcmp(text, xmlString::_CLIENT) == 0) {
        *e = DiscoveryProtocol_t::CLIENT;
    } else if (strcmp(text, xmlString::_SUPER_CLIENT) == 0) {
        *e = DiscoveryProtocol_t::SUPER_CLIENT;
    } else if (strcmp(text, xmlString::_SERVER) == 0) {
        *e = DiscoveryProtocol_t::SERVER;
    } else if (strcmp(text, xmlString::_BACKUP) == 0) {
        *e = DiscoveryProtocol_t::BACKUP;
    } else {
        elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                  "Node '" << xmlString::RTPS_PDP_TYPE << "' with bad content");
        return XMLP_ret::XML_ERROR;
    }

    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLEnum(tinyxml2::XMLElement* elem, ParticipantFilteringFlags_t* e, uint8_t /*ident*/) {

    const char* text = nullptr;

    if (nullptr == elem || nullptr == e) {
        elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "nullptr when getXMLEnum XML_ERROR!");
        return XMLP_ret::XML_ERROR;
    } else if (nullptr == (text = elem->GetText())) {
        elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "<" << elem->Value() << "> getXMLEnum XML_ERROR!");
        return XMLP_ret::XML_ERROR;
    }

    try {
        // First we check if it matches the schema pattern
        std::regex schema(
            "((FILTER_DIFFERENT_HOST|FILTER_DIFFERENT_PROCESS|FILTER_SAME_PROCESS|NO_"
            "FILTER)*(\\||\\s)*)*");

        if (!std::regex_match(text, schema)) {
            elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA,
                      "provided flags doesn't match expected ParticipantFilteringFlags!");
            return XMLP_ret::XML_ERROR;
        }

        // Lets parse the flags, we assume the flags argument has been already flushed
        std::regex flags("FILTER_DIFFERENT_HOST|FILTER_DIFFERENT_PROCESS|FILTER_SAME_PROCESS");

        std::cregex_iterator it(text, text + strlen(text), flags);
        uint32_t newflags = *e;

        while (it != std::cregex_iterator()) {
            std::string flag(it++->str());

            if (flag == xmlString::_FILTER_DIFFERENT_HOST) {
                newflags |= ParticipantFilteringFlags_t::FILTER_DIFFERENT_HOST;
            } else if (flag == xmlString::_FILTER_DIFFERENT_PROCESS) {
                newflags |= ParticipantFilteringFlags_t::FILTER_DIFFERENT_PROCESS;
            } else if (flag == xmlString::_FILTER_SAME_PROCESS) {
                newflags |= ParticipantFilteringFlags_t::FILTER_SAME_PROCESS;
            }
        }

        *e = static_cast<ParticipantFilteringFlags_t>(newflags);
    } catch (std::regex_error& e) {
        elogError(XMLPARSER, RetCode_t::RETCODE_ILLEGAL_OPERATION,
                  "getXMLEnum() Caught std::regex_error exception: " << e.what());
        return XMLP_ret::XML_ERROR;
    } catch (std::exception& e) {
        elogError(XMLPARSER, RetCode_t::RETCODE_ILLEGAL_OPERATION, "getXMLEnum() caught: " << e.what());
        return XMLP_ret::XML_ERROR;
    }

    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLString(tinyxml2::XMLElement* elem, std::string* s, uint8_t /*ident*/) {
    const char* text = nullptr;

    if ((nullptr == elem) || (nullptr == s)) {
        elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "nullptr when getXMLUint XML_ERROR!");
        return XMLP_ret::XML_ERROR;
    } else if (nullptr == (text = elem->GetText())) {
        elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "<" << elem->Value() << "> getXMLString XML_ERROR!");
        return XMLP_ret::XML_ERROR;
    }
    *s = text;
    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLguidPrefix(tinyxml2::XMLElement* elem, GuidPrefix_t& prefix, uint8_t /*ident*/) {
    const char* text = nullptr;

    if (nullptr == elem) {
        elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "nullptr when getXMLguidPrefix XML_ERROR!");
        return XMLP_ret::XML_ERROR;
    } else if (nullptr == (text = elem->GetText())) {
        elogError(XMLPARSER, RetCode_t::RETCODE_NO_DATA, "<" << elem->Value() << "> getXMLguidPrefix XML_ERROR!");
        return XMLP_ret::XML_ERROR;
    }

    std::istringstream is(text);
    return (is >> prefix ? XMLP_ret::XML_OK : XMLP_ret::XML_ERROR);
}

XMLP_ret XMLParserpart::getXMLParticipantAttributes(tinyxml2::XMLElement* elem, ParticipantAttributes& participant,
                                                    std::vector<bool>& set_flags, uint8_t ident) {
    tinyxml2::XMLElement* p_element = elem->FirstChildElement(xmlString::DOMAIN_ID);
    if (nullptr != p_element) {
        // domainId - uint32Type
        if (XMLP_ret::XML_OK != getXMLUint(p_element, &participant.domainId, ident)) {
            return XMLP_ret::XML_ERROR;
        }
        set_flags[ParticipantConfigKind::PART_CONFIG_DOMAIN_ID] = true;
    }

    std::string profile_name = getAttributeName(xmlString::PROFILE_NAME, elem);

    p_element = elem->FirstChildElement();
    if (p_element != nullptr) {
        if (XMLProfileManagerPart::getInheritanceCombinationBaseInfo(p_element->Name())) {  // participant组合
            if (XMLP_ret::XML_OK !=
                getXMLSnippetParticipantAttributes(p_element, participant, profile_name, set_flags)) {
                return XMLP_ret::XML_ERROR;
            }
        }
    }

    p_element = elem->FirstChildElement(xmlString::RTPS);
    if (nullptr == p_element) {
        return XMLP_ret::XML_OK;
    }

    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;

    std::unordered_map<std::string, bool> tags_present;
    for (p_aux0 = p_element->FirstChildElement(); p_aux0 != nullptr; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();

        if (tags_present[name]) {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Duplicated element found in 'rtpsParticipantAttributesType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
        tags_present[name] = true;

        if (strcmp(name, xmlString::ALLOCATION) == 0) {
            // allocation
            if (XMLP_ret::XML_OK != getXMLParticipantAllocationAttributes(p_aux0, participant.rtps.allocation, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[ParticipantConfigKind::PART_CONFIG_ALLOCATION] = true;
        } else if (strcmp(name, xmlString::PREFIX) == 0) {
            // prefix
            if (XMLP_ret::XML_OK != getXMLguidPrefix(p_aux0, participant.rtps.prefix, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[ParticipantConfigKind::PART_CONFIG_PREFIX] = true;
        } else if (strcmp(name, xmlString::IGN_NON_MATCHING_LOCS) == 0) {
            // ignore_non_matching_locators - boolType
            if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &participant.rtps.ignore_non_matching_locators, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[ParticipantConfigKind::PART_CONFIG_IGN_NON_MATCHING_LOCS] = true;
        } else if (strcmp(name, xmlString::DEF_EXT_UNI_LOC_LIST) == 0) {
            // default_external_unicast_locators - externalLocatorListType
            if (XMLP_ret::XML_OK !=
                getXMLExternalLocatorList(p_aux0, participant.rtps.default_external_unicast_locators, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[ParticipantConfigKind::PART_CONFIG_DEF_EXT_UNI_LOC_LIST] = true;
        } else if (strcmp(name, xmlString::DEF_UNI_LOC_LIST) == 0) {
            // defaultUnicastLocatorList
            if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux0, participant.rtps.defaultUnicastLocatorList, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[ParticipantConfigKind::PART_CONFIG_DEF_UNI_LOC_LIST] = true;
        } else if (strcmp(name, xmlString::DEF_MULTI_LOC_LIST) == 0) {
            // defaultMulticastLocatorList
            if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux0, participant.rtps.defaultMulticastLocatorList, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[ParticipantConfigKind::PART_CONFIG_DEF_MULTI_LOC_LIST] = true;
        } else if (strcmp(name, xmlString::SEND_SOCK_BUF_SIZE) == 0) {
            // sendSocketBufferSize - uint32Type
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &participant.rtps.sendSocketBufferSize, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[ParticipantConfigKind::PART_CONFIG_SEND_SOCK_BUF_SIZE] = true;
        } else if (strcmp(name, xmlString::LIST_SOCK_BUF_SIZE) == 0) {
            // listenSocketBufferSize - uint32Type
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &participant.rtps.listenSocketBufferSize, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[ParticipantConfigKind::PART_CONFIG_LIST_SOCK_BUF_SIZE] = true;
        } else if (strcmp(name, xmlString::BUILTIN) == 0) {
            // builtin
            if (XMLP_ret::XML_OK != getXMLBuiltinAttributes(p_aux0, participant.rtps.builtin, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[ParticipantConfigKind::PART_CONFIG_BUILTIN] = true;
        } else if ((strcmp(name, xmlString::STATIC_EDP_CONFIG) == 0) ||
                   (strcmp(name, xmlString::STATIC_ENDPOINT_XML_URI) == 0)) {
            std::string s = "";
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &s, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            xmlparser::DiscoverySettings& settings = participant.rtps.builtin.discovery_config;
            settings.use_SIMPLE_EndpointDiscoveryProtocol = false;
            settings.use_STATIC_EndpointDiscoveryProtocol = true;
            settings.static_edp_xml_config(s.c_str());
        } else if (strcmp(name, xmlString::PORT) == 0) {
            // port
            if (XMLP_ret::XML_OK != getXMLPortParameters(p_aux0, participant.rtps.port, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[ParticipantConfigKind::PART_CONFIG_PORT] = true;
        } else if (strcmp(name, xmlString::PART_ID) == 0) {
            // participantID - int32Type
            if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &participant.rtps.participantID, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[ParticipantConfigKind::PART_CONFIG_PART_ID] = true;
        } else if (strcmp(name, xmlString::USER_TRANS) == 0) {
            if (XMLP_ret::XML_OK !=
                getXMLTransports(p_aux0, participant.rtps.userTransports, participant.rtps.userTransportsDSF, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[ParticipantConfigKind::PART_CONFIG_USER_TRANS] = true;
        } else if (strcmp(name, xmlString::USE_BUILTIN_TRANS) == 0) {
            // useBuiltinTransports - boolType
            if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &participant.rtps.useBuiltinTransports, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[ParticipantConfigKind::PART_CONFIG_BUILTIN_TRANS] = true;
        } else if (strcmp(name, xmlString::TRANSPORT_TYPE) == 0) {
            std::string transport_type;
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &transport_type, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            if ((transport_type != xmlString::TRANSPORT_TYPE_UDP) &&
                (transport_type != xmlString::TRANSPORT_TYPE_ALL) &&
                (transport_type != xmlString::TRANSPORT_TYPE_AUTO) && (transport_type != xmlString::SHM)) {
                elogError(XMLPARSER, RetCode_t::RETCODE_ERROR, "transport_type(" << transport_type << ") invalid.");
                return XMLP_ret::XML_ERROR;
            }
            if (transport_type == xmlString::TRANSPORT_TYPE_UDP) {
                participant.rtps.transport_type = xmlparser::TRANSPORT_TYPE_UDP;
            } else if (transport_type == xmlString::TRANSPORT_TYPE_ALL) {
                if (access(constString::DSF_SHM_DRIVER_PATH, F_OK) == 0 &&
                    access(constString::DSF_SHM_DRIVER_PATH, R_OK) == 0) {
                    participant.rtps.transport_type = xmlparser::TRANSPORT_TYPE_ALL;
                } else {
                    participant.rtps.transport_type = xmlparser::TRANSPORT_TYPE_UDP;
                    logWarning(XMLPARSER,
                               "transport_type is ALL, but shm driver is not ready; fallback transport_type to UDP.");
                }
            } else if (transport_type == xmlString::TRANSPORT_TYPE_AUTO) {
                participant.rtps.transport_type = xmlparser::TRANSPORT_TYPE_AUTO;
            } else if (transport_type == xmlString::SHM) {
                participant.rtps.transport_type = xmlparser::TRANSPORT_TYPE_SHM;
            }
            set_flags[ParticipantConfigKind::PART_CONFIG_TRANSPORT_TYPE] = true;
        } else if (strcmp(name, xmlString::PROPERTIES_POLICY) == 0) {
            // propertiesPolicy
            if (XMLP_ret::XML_OK != getXMLPropertiesPolicy(p_aux0, participant.rtps.properties, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[ParticipantConfigKind::PART_CONFIG_PROPERTIES_POLICY] = true;
        } else if (strcmp(name, xmlString::FLOW_CONTROLLER) == 0) {
            // flowController
            if (XMLP_ret::XML_OK != getXMLFlowControllers(p_aux0, participant.rtps.flow_controllers, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[ParticipantConfigKind::PART_CONFIG_FLOW_CONTROLLER] = true;
        } else if (strcmp(name, xmlString::NAME) == 0) {
            // name - stringType
            std::string s;
            if (XMLP_ret::XML_OK != getXMLString(p_aux0, &s, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[ParticipantConfigKind::PART_CONFIG_NAME] = true;
            participant.rtps.setName(s.c_str());
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'rtpsParticipantAttributesType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }
    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLPublisherAttributes(tinyxml2::XMLElement* elem, PublisherAttributes& publisher,
                                                  std::vector<bool>& set_flags, uint8_t ident) {

    std::unordered_map<std::string, bool> tags_present;
    std::string profile_name = getAttributeName(xmlString::PROFILE_NAME, elem);

    WriterQos& qos = publisher.qos;
    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != nullptr; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (tags_present[name]) {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Duplicated element found in 'publisherProfileType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
        tags_present[name] = true;

        if (XMLProfileManagerPart::getInheritanceCombinationBaseInfo(name)) {  // Publisher组合
            if (XMLP_ret::XML_OK != getXMLSnippetPublisherAttributes(p_aux0, publisher, profile_name, set_flags)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::SEND_MULTI) == 0) {
            qos.m_isMultiSend = false;
            std::string auxBool = p_aux0->GetText();
            if (std::strcmp(auxBool.c_str(), "TRUE") == 0 || std::strcmp(auxBool.c_str(), "true") == 0) {
                qos.m_isMultiSend = true;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_SEND_MULTI] = true;
        } else if (strcmp(name, xmlString::HISTORY_QOS) == 0) {
            if (XMLP_ret::XML_OK != getXMLHistoryQosPolicy(p_aux0, qos.m_history, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_HISTORY_QOS] = true;
        } else if (strcmp(name, xmlString::RES_LIMITS_QOS) == 0) {
            if (XMLP_ret::XML_OK != getXMLResourceLimitsQos(p_aux0, qos.m_resourceLimits, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_RES_LIMITS_QOS] = true;
        } else if (strcmp(name, xmlString::DURABILITY) == 0) {
            if (XMLP_ret::XML_OK != getXMLDurabilityQos(p_aux0, qos.m_durability, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_DURABILITY] = true;
        } else if (strcmp(name, xmlString::LIVELINESS) == 0) {
            if (XMLP_ret::XML_OK != getXMLLivelinessQos(p_aux0, qos.m_liveliness, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_LIVELINESS] = true;
        } else if (strcmp(name, xmlString::RELIABILITY) == 0) {
            if (XMLP_ret::XML_OK != getXMLReliabilityQos(p_aux0, qos.m_reliability, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_RELIABILITY] = true;
        } else if (strcmp(name, xmlString::PARTITION) == 0) {
            if (XMLP_ret::XML_OK != getXMLPartitionQos(p_aux0, qos.m_partition, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_PARTITION] = true;
        } else if (strcmp(name, xmlString::PUB_MODE) == 0) {
            if (XMLP_ret::XML_OK != getXMLPublishModeQos(p_aux0, qos.m_publishMode, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_PUB_MODE] = true;
        } else if (strcmp(name, xmlString::DEADLINE) == 0) {
            if (XMLP_ret::XML_OK != getXMLDeadlineQos(p_aux0, qos.m_deadline, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_DEADLINE] = true;
        } else if (strcmp(name, xmlString::LIFESPAN) == 0) {
            // lifespan
            if (XMLP_ret::XML_OK != getXMLLifespanQos(p_aux0, qos.m_lifespan, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_LIFESPAN] = true;
        } else if (strcmp(name, xmlString::DISABLE_POSITIVE_ACKS) == 0) {
            if (XMLP_ret::XML_OK != getXMLDisablePositiveAcksQos(p_aux0, qos.m_disablePositiveACKs, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_DISABLE_POSITIVE_ACKS] = true;
        } else if (strcmp(name, xmlString::OWNERSHIP) == 0) {
            if (XMLP_ret::XML_OK != getXMLOwnershipQos(p_aux0, qos.m_ownership, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_OWNERSHIP] = true;
        } else if (strcmp(name, xmlString::OWNERSHIP_STRENGTH) == 0) {
            if (XMLP_ret::XML_OK != getXMLOwnershipStrengthQos(p_aux0, qos.m_ownershipStrength, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_OWNERSHIP_STRENGTH] = true;
        } else if (strcmp(name, xmlString::BATCH) == 0) {
#ifdef BATCH_SEND_ENABLE
            if (XMLP_ret::XML_OK != getXMLBatchQos(p_aux0, qos.m_batch, ident)) {
                return XMLP_ret::XML_ERROR;
            }
#endif
            set_flags[PublisherConfigKind::PUB_CONFIG_BATCH] = true;
        } else if (strcmp(name, xmlString::DISABLE_HEARTBEAT_PIGGYBACK) == 0) {
            if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &qos.disable_heartbeat_piggyback, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_DISABLE_HEARTBEAT_PIGGYBACK] = true;
        } else if (strcmp(name, xmlString::E2E_PROTECTION) == 0) {
            if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &qos.m_e2eProtecion.enabled, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_E2E_FUNCTION] = true;
        } else if (strcmp(name, xmlString::E2E_P04_MIN_DATA_LENGTH) == 0) {
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &qos.m_e2eProtecion.MinDataLength, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_E2E_FUNCTION] = true;
        } else if (strcmp(name, xmlString::E2E_P04_MAX_DATA_LENGTH) == 0) {
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &qos.m_e2eProtecion.MaxDataLength, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_E2E_FUNCTION] = true;
        } else if (strcmp(name, xmlString::E2E_P04_MAX_DELTA_COUNTER) == 0) {
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &qos.m_e2eProtecion.MaxDeltaCounter, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_E2E_FUNCTION] = true;
        } else if (strcmp(name, xmlString::E2E_DEADLINE_COUNTER) == 0) {
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &qos.m_deadline.counter, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            qos.m_deadline.using_e2e_config = true;
            set_flags[PublisherConfigKind::PUB_CONFIG_E2E_FUNCTION] = true;
        } else if (strcmp(name, xmlString::E2E_LIVELINESS_KIND) == 0) {
            if (XMLP_ret::XML_OK != getXMLLivelinessKind(p_aux0, qos.m_liveliness.kind, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            qos.m_liveliness.using_e2e_config = true;
            set_flags[PublisherConfigKind::PUB_CONFIG_E2E_FUNCTION] = true;
        } else if (strcmp(name, xmlString::E2E_LIVELINESS_LEASE_DURATION) == 0) {
            if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, qos.m_liveliness.lease_duration, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            qos.m_liveliness.using_e2e_config = true;
            set_flags[PublisherConfigKind::PUB_CONFIG_E2E_FUNCTION] = true;
        } else if (strcmp(name, xmlString::HEARTBEAT_PER_MAX_SAMPLE) == 0) {
            if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &qos.heartbeat_per_max_samples, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_HEARTBEAT_PER_MAX_SAMPLE] = true;
        } else if (strcmp(name, xmlString::TIMES) == 0) {
            if (XMLP_ret::XML_OK != getXMLWriterTimes(p_aux0, publisher.times, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_TIMES] = true;
        } else if (strcmp(name, xmlString::IGN_NON_MATCHING_LOCS) == 0) {
            if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &publisher.ignore_non_matching_locators, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_IGN_NON_MATCHING_LOCS] = true;
        } else if (strcmp(name, xmlString::EXT_UNI_LOC_LIST) == 0) {
            if (XMLP_ret::XML_OK != getXMLExternalLocatorList(p_aux0, publisher.external_unicast_locators, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_EXT_UNI_LOC_LIST] = true;
        } else if (strcmp(name, xmlString::UNI_LOC_LIST) == 0) {
            if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux0, publisher.unicastLocatorList, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_UNI_LOC_LIST] = true;
        } else if (strcmp(name, xmlString::MULTI_LOC_LIST) == 0) {
            if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux0, publisher.multicastLocatorList, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_MULTI_LOC_LIST] = true;
        } else if (strcmp(name, xmlString::REM_LOC_LIST) == 0) {
            if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux0, publisher.remoteLocatorList, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_REM_LOC_LIST] = true;
        } else if (strcmp(name, xmlString::HIST_MEM_POLICY) == 0) {
            if (XMLP_ret::XML_OK != getXMLHistoryMemoryPolicy(p_aux0, publisher.historyMemoryPolicy, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_HIST_MEM_POLICY] = true;
        } else if (strcmp(name, xmlString::PROPERTIES_POLICY) == 0) {
            if (XMLP_ret::XML_OK != getXMLPropertiesPolicy(p_aux0, publisher.properties, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_PROPERTIES_POLICY] = true;
        } else if (strcmp(name, xmlString::USER_DEF_ID) == 0) {
            // userDefinedID - int16type
            int i = 0;
            if ((XMLP_ret::XML_OK != getXMLInt(p_aux0, &i, ident)) || (i > SHRT_MAX)) {
                return XMLP_ret::XML_ERROR;
            }
            publisher.setUserDefinedID(static_cast<uint16_t>(i));
            set_flags[PublisherConfigKind::PUB_CONFIG_USER_DEF_ID] = true;
        } else if (strcmp(name, xmlString::ENTITY_ID) == 0) {
            // entityID - int16Type
            int i = 0;
            if ((XMLP_ret::XML_OK != getXMLInt(p_aux0, &i, ident)) || (i > SHRT_MAX)) {
                return XMLP_ret::XML_ERROR;
            }
            publisher.setEntityID(static_cast<uint16_t>(i));
            set_flags[PublisherConfigKind::PUB_CONFIG_ENTITY_ID] = true;
        } else if (strcmp(name, xmlString::MATCHED_SUBSCRIBERS_ALLOCATION) == 0) {
            // matchedSubscribersAllocation - containerAllocationConfigType
            if (XMLP_ret::XML_OK !=
                getXMLContainerAllocationConfig(p_aux0, publisher.matched_subscriber_allocation, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_MATCHED_SUBSCRIBERS_ALLOCATION] = true;
        } else if (strcmp(name, xmlString::HIGH_WATERMARK) == 0) {
            if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &qos.high_watermark, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_HIGH_WATERMARK] = true;
        } else if (strcmp(name, xmlString::LOW_WATERMARK) == 0) {
            if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &qos.low_watermark, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[PublisherConfigKind::PUB_CONFIG_LOW_WATERMARK] = true;
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'publisherProfileType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }
    return XMLP_ret::XML_OK;
}

XMLP_ret XMLParserpart::getXMLSubscriberAttributes(tinyxml2::XMLElement* elem, SubscriberAttributes& subscriber,
                                                   std::vector<bool>& set_flags, uint8_t ident) {

    std::unordered_map<std::string, bool> tags_present;
    std::string profile_name = getAttributeName(xmlString::PROFILE_NAME, elem);

    ReaderQos& qos = subscriber.qos;
    tinyxml2::XMLElement* p_aux0 = nullptr;
    const char* name = nullptr;
    for (p_aux0 = elem->FirstChildElement(); p_aux0 != nullptr; p_aux0 = p_aux0->NextSiblingElement()) {
        name = p_aux0->Name();
        if (tags_present[name]) {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Duplicated element found in 'subscriberProfileType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
        tags_present[name] = true;

        if (XMLProfileManagerPart::getInheritanceCombinationBaseInfo(name)) {  // Subscriber组合
            if (XMLP_ret::XML_OK != getXMLSnippetSubscriberAttributes(p_aux0, subscriber, profile_name, set_flags)) {
                return XMLP_ret::XML_ERROR;
            }
        } else if (strcmp(name, xmlString::SEND_MULTI) == 0) {
            qos.m_isMultiSend = false;
            std::string auxBool = p_aux0->GetText();
            if (std::strcmp(auxBool.c_str(), "TRUE") == 0 || std::strcmp(auxBool.c_str(), "true") == 0) {
                qos.m_isMultiSend = true;
            }
            set_flags[SubscriberConfigKind::SUB_CONFIG_SEND_MULTI] = true;
        } else if (strcmp(name, xmlString::HISTORY_QOS) == 0) {
            if (XMLP_ret::XML_OK != getXMLHistoryQosPolicy(p_aux0, qos.m_history, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[SubscriberConfigKind::SUB_CONFIG_HISTORY_QOS] = true;
        } else if (strcmp(name, xmlString::RES_LIMITS_QOS) == 0) {
            if (XMLP_ret::XML_OK != getXMLResourceLimitsQos(p_aux0, qos.m_resourceLimits, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[SubscriberConfigKind::SUB_CONFIG_RES_LIMITS_QOS] = true;
        } else if (strcmp(name, xmlString::DURABILITY) == 0) {
            if (XMLP_ret::XML_OK != getXMLDurabilityQos(p_aux0, qos.m_durability, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[SubscriberConfigKind::SUB_CONFIG_DURABILITY] = true;
        } else if (strcmp(name, xmlString::LIVELINESS) == 0) {
            if (XMLP_ret::XML_OK != getXMLLivelinessQos(p_aux0, qos.m_liveliness, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[SubscriberConfigKind::SUB_CONFIG_LIVELINESS] = true;
        } else if (strcmp(name, xmlString::RELIABILITY) == 0) {
            if (XMLP_ret::XML_OK != getXMLReliabilityQos(p_aux0, qos.m_reliability, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[SubscriberConfigKind::SUB_CONFIG_RELIABILITY] = true;
        } else if (strcmp(name, xmlString::PARTITION) == 0) {
            if (XMLP_ret::XML_OK != getXMLPartitionQos(p_aux0, qos.m_partition, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[SubscriberConfigKind::SUB_CONFIG_PARTITION] = true;
        } else if (strcmp(name, xmlString::DEADLINE) == 0) {
            if (XMLP_ret::XML_OK != getXMLDeadlineQos(p_aux0, qos.m_deadline, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[SubscriberConfigKind::SUB_CONFIG_DEADLINE] = true;
        } else if (strcmp(name, xmlString::LIFESPAN) == 0) {
            if (XMLP_ret::XML_OK != getXMLLifespanQos(p_aux0, qos.m_lifespan, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[SubscriberConfigKind::SUB_CONFIG_LIFESPAN] = true;
        } else if (strcmp(name, xmlString::DISABLE_POSITIVE_ACKS) == 0) {
            if (XMLP_ret::XML_OK != getXMLDisablePositiveAcksQos(p_aux0, qos.m_disablePositiveACKs, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[SubscriberConfigKind::SUB_CONFIG_DISABLE_POSITIVE_ACKS] = true;
        } else if (strcmp(name, xmlString::OWNERSHIP) == 0) {
            if (XMLP_ret::XML_OK != getXMLOwnershipQos(p_aux0, qos.m_ownership, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[SubscriberConfigKind::SUB_CONFIG_OWNERSHIP] = true;
        } else if (strcmp(name, xmlString::E2E_PROTECTION) == 0) {
            if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &qos.m_e2eProtecion.enabled, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[SubscriberConfigKind::SUB_CONFIG_E2E_FUNCTION] = true;
        } else if (strcmp(name, xmlString::E2E_P04_MIN_DATA_LENGTH) == 0) {
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &qos.m_e2eProtecion.MinDataLength, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[SubscriberConfigKind::SUB_CONFIG_E2E_FUNCTION] = true;
        } else if (strcmp(name, xmlString::E2E_P04_MAX_DATA_LENGTH) == 0) {
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &qos.m_e2eProtecion.MaxDataLength, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[SubscriberConfigKind::SUB_CONFIG_E2E_FUNCTION] = true;
        } else if (strcmp(name, xmlString::E2E_P04_MAX_DELTA_COUNTER) == 0) {
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &qos.m_e2eProtecion.MaxDeltaCounter, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[SubscriberConfigKind::SUB_CONFIG_E2E_FUNCTION] = true;
        } else if (strcmp(name, xmlString::E2E_DEADLINE_COUNTER) == 0) {
            if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &qos.m_deadline.counter, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            qos.m_deadline.using_e2e_config = true;
            set_flags[SubscriberConfigKind::SUB_CONFIG_E2E_FUNCTION] = true;
        } else if (strcmp(name, xmlString::E2E_LIVELINESS_KIND) == 0) {
            if (XMLP_ret::XML_OK != getXMLLivelinessKind(p_aux0, qos.m_liveliness.kind, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            qos.m_liveliness.using_e2e_config = true;
            set_flags[PublisherConfigKind::PUB_CONFIG_E2E_FUNCTION] = true;
        } else if (strcmp(name, xmlString::E2E_LIVELINESS_LEASE_DURATION) == 0) {
            if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, qos.m_liveliness.lease_duration, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            qos.m_liveliness.using_e2e_config = true;
            set_flags[PublisherConfigKind::PUB_CONFIG_E2E_FUNCTION] = true;
        } else if (strcmp(name, xmlString::TIMES) == 0) {
            if (XMLP_ret::XML_OK != getXMLReaderTimes(p_aux0, subscriber.times, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[SubscriberConfigKind::SUB_CONFIG_TIMES] = true;
        } else if (strcmp(name, xmlString::IGN_NON_MATCHING_LOCS) == 0) {
            if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &subscriber.ignore_non_matching_locators, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[SubscriberConfigKind::SUB_CONFIG_IGN_NON_MATCHING_LOCS] = true;
        } else if (strcmp(name, xmlString::EXT_UNI_LOC_LIST) == 0) {
            if (XMLP_ret::XML_OK != getXMLExternalLocatorList(p_aux0, subscriber.external_unicast_locators, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[SubscriberConfigKind::SUB_CONFIG_EXT_UNI_LOC_LIST] = true;
        } else if (strcmp(name, xmlString::UNI_LOC_LIST) == 0) {
            if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux0, subscriber.unicastLocatorList, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[SubscriberConfigKind::SUB_CONFIG_UNI_LOC_LIST] = true;
        } else if (strcmp(name, xmlString::MULTI_LOC_LIST) == 0) {
            if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux0, subscriber.multicastLocatorList, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[SubscriberConfigKind::SUB_CONFIG_MULTI_LOC_LIST] = true;
        } else if (strcmp(name, xmlString::REM_LOC_LIST) == 0) {
            if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux0, subscriber.remoteLocatorList, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[SubscriberConfigKind::SUB_CONFIG_REM_LOC_LIST] = true;
        } else if (strcmp(name, xmlString::HIST_MEM_POLICY) == 0) {
            if (XMLP_ret::XML_OK != getXMLHistoryMemoryPolicy(p_aux0, subscriber.historyMemoryPolicy, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[SubscriberConfigKind::SUB_CONFIG_HIST_MEM_POLICY] = true;
        } else if (strcmp(name, xmlString::PROPERTIES_POLICY) == 0) {
            if (XMLP_ret::XML_OK != getXMLPropertiesPolicy(p_aux0, subscriber.properties, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[SubscriberConfigKind::SUB_CONFIG_PROPERTIES_POLICY] = true;
        } else if (strcmp(name, xmlString::USER_DEF_ID) == 0) {
            int i = 0;
            if ((XMLP_ret::XML_OK != getXMLInt(p_aux0, &i, ident)) || (i > SHRT_MAX)) {
                return XMLP_ret::XML_ERROR;
            }
            subscriber.setUserDefinedID(static_cast<uint16_t>(i));
            set_flags[SubscriberConfigKind::SUB_CONFIG_USER_DEF_ID] = true;
        } else if (strcmp(name, xmlString::ENTITY_ID) == 0) {
            int i = 0;
            if ((XMLP_ret::XML_OK != getXMLInt(p_aux0, &i, ident)) || (i > SHRT_MAX)) {
                return XMLP_ret::XML_ERROR;
            }
            subscriber.setEntityID(static_cast<uint16_t>(i));
            set_flags[SubscriberConfigKind::SUB_CONFIG_ENTITY_ID] = true;
        } else if (strcmp(name, xmlString::MATCHED_PUBLISHERS_ALLOCATION) == 0) {
            // matchedPublishersAllocation - containerAllocationConfigType
            if (XMLP_ret::XML_OK !=
                getXMLContainerAllocationConfig(p_aux0, subscriber.matched_publisher_allocation, ident)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[SubscriberConfigKind::SUB_CONFIG_MATCHED_PUBLISHERS_ALLOCATION] = true;
        } else if (strcmp(name, xmlString::DEST_ORDER) == 0) {
            if (XMLP_ret::XML_OK != getXMLDestinationOrderQos(p_aux0, qos.m_destinationOrder)) {
                return XMLP_ret::XML_ERROR;
            }
            set_flags[SubscriberConfigKind::SUB_CONFIG_DESTINATION_ORDER] = true;
        } else {
            elogError(XMLPARSER, RetCode_t::RETCODE_BAD_PARAMETER,
                      "Invalid element found into 'subscriberProfileType'. Name: " << name);
            return XMLP_ret::XML_ERROR;
        }
    }
    return XMLP_ret::XML_OK;
}

void createBuildInAttributesEntity(std::string name) {
    XMLProfileManagerPart::participant_profiles_[name] = up_participant_t(new ParticipantAttributes());
    XMLProfileManagerPart::publisher_profiles_[name] = up_publisher_t(new PublisherAttributes());
    XMLProfileManagerPart::subscriber_profiles_[name] = up_subscriber_t(new SubscriberAttributes());

    std::vector<bool> set_flags_part(ParticipantConfigKind::PART_CONFIG_END);
    std::vector<bool> set_flags_pub(PublisherConfigKind::PUB_CONFIG_END);
    std::vector<bool> set_flags_sub(SubscriberConfigKind::SUB_CONFIG_END);
    XMLProfileManagerPart::participant_profile_set_flags_.emplace(name, set_flags_part);
    XMLProfileManagerPart::publisher_profile_set_flags_.emplace(name, set_flags_pub);
    XMLProfileManagerPart::subscriber_profile_set_flags_.emplace(name, set_flags_sub);
}

void fillBuiltinQosSnippetLibOptimizationReliabilityProtocolCommon(std::string name) {
    XMLProfileManagerPart::publisher_profiles_[name].get()->qos.heartbeat_per_max_samples = 10;
    XMLProfileManagerPart::publisher_profiles_[name].get()->times.heartbeatPeriod.seconds = 0;
    XMLProfileManagerPart::publisher_profiles_[name].get()->times.heartbeatPeriod.nanosec = 200000000;
    XMLProfileManagerPart::publisher_profiles_[name].get()->times.initialHeartbeatDelay.seconds = 0;
    XMLProfileManagerPart::publisher_profiles_[name].get()->times.initialHeartbeatDelay.nanosec = 20000000;
    XMLProfileManagerPart::publisher_profiles_[name].get()->times.nackResponseDelay = 0;
    XMLProfileManagerPart::subscriber_profiles_[name].get()->qos.m_resourceLimits.max_samples = 256;
    XMLProfileManagerPart::subscriber_profiles_[name].get()->times.initialAcknackDelay = 0;

    XMLProfileManagerPart::publisher_profile_set_flags_[name]
                                                       [PublisherConfigKind::PUB_CONFIG_HEARTBEAT_PER_MAX_SAMPLE] =
                                                           true;
    XMLProfileManagerPart::publisher_profile_set_flags_[name][PublisherConfigKind::PUB_CONFIG_TIMES] = true;
    XMLProfileManagerPart::subscriber_profile_set_flags_[name][SubscriberConfigKind::SUB_CONFIG_RES_LIMITS_QOS] = true;
    XMLProfileManagerPart::subscriber_profile_set_flags_[name][SubscriberConfigKind::SUB_CONFIG_TIMES] = true;
}

void fillBuiltinQosSnippetLibOptimizationReliabilityProtocolKeepAll(std::string name) {
    // 组合 <value>BuiltinQosSnippetLib::Optimization.ReliabilityProtocol.Common</value>
    fillBuiltinQosSnippetLibOptimizationReliabilityProtocolCommon(std::move(name));
}

void fillBuiltinQosSnippetLibOptimizationReliabilityProtocolKeepLast(std::string name) {
    // 组合 <value>BuiltinQosSnippetLib::Optimization.ReliabilityProtocol.Common</value>
    fillBuiltinQosSnippetLibOptimizationReliabilityProtocolCommon(name);
    // publisher
    XMLProfileManagerPart::publisher_profiles_[name].get()->qos.m_resourceLimits.max_samples = 0x7fffffff;
    // subscriber
    XMLProfileManagerPart::subscriber_profiles_[name].get()->qos.m_resourceLimits.max_samples = 0x7fffffff;

    XMLProfileManagerPart::publisher_profile_set_flags_[name][PublisherConfigKind::PUB_CONFIG_RES_LIMITS_QOS] = true;
    XMLProfileManagerPart::subscriber_profile_set_flags_[name][SubscriberConfigKind::SUB_CONFIG_RES_LIMITS_QOS] = true;
}

void fillBuiltinQosSnippetLibQosPolicyReliabilityReliable(std::string name) {
    XMLProfileManagerPart::publisher_profiles_[name].get()->qos.m_reliability.kind = RELIABLE_RELIABILITY_QOS;
    XMLProfileManagerPart::publisher_profiles_[name].get()->qos.m_reliability.max_blocking_time.seconds = 5;
    XMLProfileManagerPart::publisher_profiles_[name].get()->qos.m_reliability.max_blocking_time.nanosec = 0;
    XMLProfileManagerPart::subscriber_profiles_[name].get()->qos.m_reliability.kind = RELIABLE_RELIABILITY_QOS;

    XMLProfileManagerPart::publisher_profile_set_flags_[name][PublisherConfigKind::PUB_CONFIG_RELIABILITY] = true;
    XMLProfileManagerPart::subscriber_profile_set_flags_[name][SubscriberConfigKind::SUB_CONFIG_RELIABILITY] = true;
}

void fillBuiltinQosSnippetLibQosPolicyReliabilityBestEffort(std::string name) {
    XMLProfileManagerPart::publisher_profiles_[name].get()->qos.m_reliability.kind = BEST_EFFORT_RELIABILITY_QOS;
    XMLProfileManagerPart::subscriber_profiles_[name].get()->qos.m_reliability.kind = BEST_EFFORT_RELIABILITY_QOS;

    XMLProfileManagerPart::publisher_profile_set_flags_[name][PublisherConfigKind::PUB_CONFIG_RELIABILITY] = true;
    XMLProfileManagerPart::subscriber_profile_set_flags_[name][SubscriberConfigKind::SUB_CONFIG_RELIABILITY] = true;
}

void fillBuiltinQosSnippetLibQosPolicyHistoryKeepLast_1(std::string name) {
    XMLProfileManagerPart::publisher_profiles_[name].get()->qos.m_history.kind = KEEP_LAST_HISTORY_QOS;
    XMLProfileManagerPart::publisher_profiles_[name].get()->qos.m_history.depth = 1;
    XMLProfileManagerPart::subscriber_profiles_[name].get()->qos.m_history.kind = KEEP_LAST_HISTORY_QOS;
    XMLProfileManagerPart::subscriber_profiles_[name].get()->qos.m_history.depth = 1;

    XMLProfileManagerPart::publisher_profile_set_flags_[name][PublisherConfigKind::PUB_CONFIG_HISTORY_QOS] = true;
    XMLProfileManagerPart::subscriber_profile_set_flags_[name][SubscriberConfigKind::SUB_CONFIG_HISTORY_QOS] = true;
}

void fillBuiltinQosSnippetLibQosPolicyHistoryKeepAll(std::string name) {
    XMLProfileManagerPart::publisher_profiles_[name].get()->qos.m_history.kind = KEEP_ALL_HISTORY_QOS;
    XMLProfileManagerPart::subscriber_profiles_[name].get()->qos.m_history.kind = KEEP_ALL_HISTORY_QOS;

    XMLProfileManagerPart::publisher_profile_set_flags_[name][PublisherConfigKind::PUB_CONFIG_HISTORY_QOS] = true;
    XMLProfileManagerPart::subscriber_profile_set_flags_[name][SubscriberConfigKind::SUB_CONFIG_HISTORY_QOS] = true;
}

void fillBuiltinQosSnippetLibQosPolicyPublishModeAsynchronous(std::string name) {
    XMLProfileManagerPart::publisher_profiles_[name].get()->qos.m_publishMode.kind = ASYNCHRONOUS_PUBLISH_MODE;

    XMLProfileManagerPart::publisher_profile_set_flags_[name][PublisherConfigKind::PUB_CONFIG_PUB_MODE] = true;
}

void fillBuiltinQosSnippetLibQosPolicyDurabilityTransientLocal(std::string name) {
    XMLProfileManagerPart::publisher_profiles_[name].get()->qos.m_durability.kind = TRANSIENT_LOCAL_DURABILITY_QOS;
    XMLProfileManagerPart::subscriber_profiles_[name].get()->qos.m_durability.kind = TRANSIENT_LOCAL_DURABILITY_QOS;

    XMLProfileManagerPart::publisher_profile_set_flags_[name][PublisherConfigKind::PUB_CONFIG_DURABILITY] = true;
    XMLProfileManagerPart::subscriber_profile_set_flags_[name][SubscriberConfigKind::SUB_CONFIG_DURABILITY] = true;
}

void fillBuiltinQosLibGenericCommon(std::string name) {
    Property prop;
    // participant
    XMLProfileManagerPart::participant_profiles_[name].get()->rtps.transport_type = TRANSPORT_TYPE_ALL;
    XMLProfileManagerPart::participant_profiles_[name]
        .get()
        ->rtps.builtin.discovery_config.leaseDuration_announcementperiod.seconds = 30;
    XMLProfileManagerPart::participant_profiles_[name]
        .get()
        ->rtps.builtin.discovery_config.leaseDuration_announcementperiod.nanosec = 0;
    XMLProfileManagerPart::participant_profiles_[name].get()->rtps.builtin.discovery_config.leaseDuration.seconds = 100;
    XMLProfileManagerPart::participant_profiles_[name]
        .get()
        ->rtps.builtin.discovery_config.initial_announcements.count = 10;
    XMLProfileManagerPart::participant_profiles_[name]
        .get()
        ->rtps.builtin.discovery_config.initial_announcements.period.seconds = 0;
    XMLProfileManagerPart::participant_profiles_[name]
        .get()
        ->rtps.builtin.discovery_config.initial_announcements.period.nanosec = 100000000;
    XMLProfileManagerPart::participant_profiles_[name].get()->rtps.useBuiltinTransports = false;

    XMLProfileManagerPart::participant_profile_set_flags_[name][ParticipantConfigKind::PART_CONFIG_TRANSPORT_TYPE] =
        true;
    XMLProfileManagerPart::participant_profile_set_flags_[name][ParticipantConfigKind::PART_CONFIG_BUILTIN] = true;
    XMLProfileManagerPart::participant_profile_set_flags_[name][ParticipantConfigKind::PART_CONFIG_BUILTIN_TRANS] =
        true;

    // publisher
    prop.name("dsf.mbuf.pool_size");
    prop.value("3145728");
    XMLProfileManagerPart::publisher_profiles_[name].get()->properties.properties().push_back(prop);
    prop.name("dsf.mbuf.max_allocation");
    prop.value("48");
    XMLProfileManagerPart::publisher_profiles_[name].get()->properties.properties().push_back(prop);
    XMLProfileManagerPart::publisher_profiles_[name].get()->qos.m_history.kind = KEEP_LAST_HISTORY_QOS;
    XMLProfileManagerPart::publisher_profiles_[name].get()->qos.m_history.depth = 1;
    XMLProfileManagerPart::publisher_profiles_[name].get()->qos.m_durability.kind = VOLATILE_DURABILITY_QOS;
    XMLProfileManagerPart::publisher_profiles_[name].get()->qos.m_liveliness.kind = AUTOMATIC_LIVELINESS_QOS;
    XMLProfileManagerPart::publisher_profiles_[name].get()->qos.m_reliability.kind = RELIABLE_RELIABILITY_QOS;
    XMLProfileManagerPart::publisher_profiles_[name].get()->qos.m_reliability.max_blocking_time.seconds = 0;
    XMLProfileManagerPart::publisher_profiles_[name].get()->qos.m_reliability.max_blocking_time.nanosec = 100000000;
    XMLProfileManagerPart::publisher_profiles_[name].get()->qos.m_publishMode.kind = SYNCHRONOUS_PUBLISH_MODE;
    XMLProfileManagerPart::publisher_profiles_[name].get()->times.heartbeatPeriod.seconds = 3;
    XMLProfileManagerPart::publisher_profiles_[name].get()->times.heartbeatPeriod.nanosec = 0;
    XMLProfileManagerPart::publisher_profiles_[name].get()->times.nackResponseDelay = 0;
    XMLProfileManagerPart::publisher_profiles_[name].get()->times.nackSupressionDuration = 0;
    XMLProfileManagerPart::publisher_profiles_[name].get()->qos.m_isMultiSend = true;
    XMLProfileManagerPart::publisher_profiles_[name].get()->historyMemoryPolicy = PREALLOCATED_WITH_REALLOC_MEMORY_MODE;

    XMLProfileManagerPart::publisher_profile_set_flags_[name][PublisherConfigKind::PUB_CONFIG_HISTORY_QOS] = true;
    XMLProfileManagerPart::publisher_profile_set_flags_[name][PublisherConfigKind::PUB_CONFIG_DURABILITY] = true;
    XMLProfileManagerPart::publisher_profile_set_flags_[name][PublisherConfigKind::PUB_CONFIG_LIVELINESS] = true;
    XMLProfileManagerPart::publisher_profile_set_flags_[name][PublisherConfigKind::PUB_CONFIG_RELIABILITY] = true;
    XMLProfileManagerPart::publisher_profile_set_flags_[name][PublisherConfigKind::PUB_CONFIG_PUB_MODE] = true;
    XMLProfileManagerPart::publisher_profile_set_flags_[name][PublisherConfigKind::PUB_CONFIG_TIMES] = true;
    XMLProfileManagerPart::publisher_profile_set_flags_[name][PublisherConfigKind::PUB_CONFIG_SEND_MULTI] = true;
    XMLProfileManagerPart::publisher_profile_set_flags_[name][PublisherConfigKind::PUB_CONFIG_HIST_MEM_POLICY] = true;

    // subscriber
    prop.name("dsf.queue.size");
    prop.value("32");
    XMLProfileManagerPart::subscriber_profiles_[name].get()->properties.properties().push_back(std::move(prop));
    XMLProfileManagerPart::subscriber_profiles_[name].get()->qos.m_history.kind = KEEP_LAST_HISTORY_QOS;
    XMLProfileManagerPart::subscriber_profiles_[name].get()->qos.m_history.depth = 1;
    XMLProfileManagerPart::subscriber_profiles_[name].get()->qos.m_durability.kind = VOLATILE_DURABILITY_QOS;
    XMLProfileManagerPart::subscriber_profiles_[name].get()->qos.m_liveliness.kind = AUTOMATIC_LIVELINESS_QOS;
    XMLProfileManagerPart::subscriber_profiles_[name].get()->qos.m_reliability.kind = BEST_EFFORT_RELIABILITY_QOS;
    XMLProfileManagerPart::subscriber_profiles_[name].get()->qos.m_reliability.max_blocking_time.seconds = 0;
    XMLProfileManagerPart::subscriber_profiles_[name].get()->qos.m_reliability.max_blocking_time.nanosec = 100000000;
    XMLProfileManagerPart::subscriber_profiles_[name].get()->qos.m_isMultiSend = true;
    XMLProfileManagerPart::subscriber_profiles_[name].get()->historyMemoryPolicy =
        PREALLOCATED_WITH_REALLOC_MEMORY_MODE;

    XMLProfileManagerPart::subscriber_profile_set_flags_[name][SubscriberConfigKind::SUB_CONFIG_HISTORY_QOS] = true;
    XMLProfileManagerPart::subscriber_profile_set_flags_[name][SubscriberConfigKind::SUB_CONFIG_DURABILITY] = true;
    XMLProfileManagerPart::subscriber_profile_set_flags_[name][SubscriberConfigKind::SUB_CONFIG_LIVELINESS] = true;
    XMLProfileManagerPart::subscriber_profile_set_flags_[name][SubscriberConfigKind::SUB_CONFIG_RELIABILITY] = true;
    XMLProfileManagerPart::subscriber_profile_set_flags_[name][SubscriberConfigKind::SUB_CONFIG_SEND_MULTI] = true;
    XMLProfileManagerPart::subscriber_profile_set_flags_[name][SubscriberConfigKind::SUB_CONFIG_HIST_MEM_POLICY] = true;
}

void fillBuiltinQosLibGenericStrictReliable(std::string name) {
    fillBuiltinQosLibGenericCommon(name);  // base_name="BuiltinQosLib::Generic.Common"
    fillBuiltinQosSnippetLibQosPolicyReliabilityReliable(
        name);  // <value>BuiltinQosSnippetLib::QosPolicy.Reliability.Reliable</value>
    fillBuiltinQosSnippetLibQosPolicyHistoryKeepAll(
        name);  // <value>BuiltinQosSnippetLib::QosPolicy.History.KeepAll</value>
    fillBuiltinQosSnippetLibOptimizationReliabilityProtocolKeepAll(
        std::move(name));  // <value>BuiltinQosSnippetLib::Optimization.ReliabilityProtocol.KeepAll</value>
}

void fillBuiltinQosLibGenericKeepLastReliable(std::string name) {
    fillBuiltinQosLibGenericCommon(name);  // base_name="BuiltinQosLib::Generic.Common"
    fillBuiltinQosSnippetLibQosPolicyReliabilityReliable(
        name);  // <value>BuiltinQosSnippetLib::QosPolicy.Reliability.Reliable</value>
    fillBuiltinQosSnippetLibQosPolicyHistoryKeepLast_1(
        name);  // <value>BuiltinQosSnippetLib::QosPolicy.History.KeepLast_1</value>
    fillBuiltinQosSnippetLibOptimizationReliabilityProtocolKeepLast(
        std::move(name));  // <value>BuiltinQosSnippetLib::Optimization.ReliabilityProtocol.KeepLast</value>
}

void fillBuiltinQosLibGenericBestEffort(std::string name) {
    fillBuiltinQosLibGenericCommon(name);  // base_name="BuiltinQosLib::Generic.Common"
    fillBuiltinQosSnippetLibQosPolicyReliabilityBestEffort(
        name);  // <value>BuiltinQosSnippetLib::QosPolicy.Reliability.BestEffort</value>
    fillBuiltinQosSnippetLibQosPolicyHistoryKeepLast_1(
        name);  // <value>BuiltinQosSnippetLib::QosPolicy.History.KeepLast_1</value>
    XMLProfileManagerPart::publisher_profiles_[name].get()->qos.m_history.depth = 100;
    XMLProfileManagerPart::subscriber_profiles_[name].get()->qos.m_history.depth = 100;

    XMLProfileManagerPart::publisher_profile_set_flags_[name][PublisherConfigKind::PUB_CONFIG_HISTORY_QOS] = true;
    XMLProfileManagerPart::subscriber_profile_set_flags_[name][SubscriberConfigKind::SUB_CONFIG_RELIABILITY] = true;
}

void fillBuiltinQosLibGenericKeepLastReliableTransientLocal(std::string name) {
    fillBuiltinQosLibGenericCommon(name);  // base_name="BuiltinQosLib::Generic.Common"
    fillBuiltinQosSnippetLibQosPolicyReliabilityReliable(
        name);  // <value>BuiltinQosSnippetLib::QosPolicy.Reliability.Reliable</value>
    fillBuiltinQosSnippetLibQosPolicyHistoryKeepLast_1(
        name);  // <value>BuiltinQosSnippetLib::QosPolicy.History.KeepLast_1</value>
    fillBuiltinQosSnippetLibOptimizationReliabilityProtocolKeepLast(
        name);  // <value>BuiltinQosSnippetLib::Optimization.ReliabilityProtocol.KeepLast</value>
    fillBuiltinQosSnippetLibQosPolicyDurabilityTransientLocal(
        std::move(name));  // <value>BuiltinQosSnippetLib::QosPolicy.Durability.TransientLocal</value>
}

void fillBuiltinQosLibPatternStatus(std::string name) {
    fillBuiltinQosLibGenericKeepLastReliableTransientLocal(std::move(name));
}

void fillBuiltinQosLibPatternLastValueCache(std::string name) {
    fillBuiltinQosLibGenericKeepLastReliableTransientLocal(std::move(name));
}

void XMLParserpart::fillBuildinProfilesAttributes() {
    // fillBuildinAttributes中函数调用顺序不可随意更换，资源有时序依赖
    std::lock(XMLProfileManagerPart::mtx_xml_participant_profiles_, XMLProfileManagerPart::mtx_xml_publisher_profiles_,
              XMLProfileManagerPart::mtx_xml_subscriber_profiles_);
    std::lock_guard<std::mutex> lock1(XMLProfileManagerPart::mtx_xml_participant_profiles_, std::adopt_lock);
    std::lock_guard<std::mutex> lock2(XMLProfileManagerPart::mtx_xml_publisher_profiles_, std::adopt_lock);
    std::lock_guard<std::mutex> lock3(XMLProfileManagerPart::mtx_xml_subscriber_profiles_, std::adopt_lock);

    std::string name = "";

    name = "BuiltinQosSnippetLib::Optimization.ReliabilityProtocol.Common";
    createBuildInAttributesEntity(name);
    fillBuiltinQosSnippetLibOptimizationReliabilityProtocolCommon(name);

    name = "BuiltinQosSnippetLib::Optimization.ReliabilityProtocol.KeepAll";
    createBuildInAttributesEntity(name);
    fillBuiltinQosSnippetLibOptimizationReliabilityProtocolKeepAll(name);

    name = "BuiltinQosSnippetLib::Optimization.ReliabilityProtocol.KeepLast";
    createBuildInAttributesEntity(name);
    fillBuiltinQosSnippetLibOptimizationReliabilityProtocolKeepLast(name);

    name = "BuiltinQosSnippetLib::Optimization.Discovery.Participant.Compact";
    createBuildInAttributesEntity(name);

    name = "BuiltinQosSnippetLib::QosPolicy.Reliability.Reliable";
    createBuildInAttributesEntity(name);
    fillBuiltinQosSnippetLibQosPolicyReliabilityReliable(name);

    name = "BuiltinQosSnippetLib::QosPolicy.Reliability.BestEffort";
    createBuildInAttributesEntity(name);
    fillBuiltinQosSnippetLibQosPolicyReliabilityBestEffort(name);

    name = "BuiltinQosSnippetLib::QosPolicy.History.KeepLast_1";
    createBuildInAttributesEntity(name);
    fillBuiltinQosSnippetLibQosPolicyHistoryKeepLast_1(name);

    name = "BuiltinQosSnippetLib::QosPolicy.History.KeepAll";
    createBuildInAttributesEntity(name);
    fillBuiltinQosSnippetLibQosPolicyHistoryKeepAll(name);

    name = "BuiltinQosSnippetLib::QosPolicy.PublishMode.Asynchronous";
    createBuildInAttributesEntity(name);
    fillBuiltinQosSnippetLibQosPolicyPublishModeAsynchronous(name);

    name = "BuiltinQosSnippetLib::QosPolicy.Durability.TransientLocal";
    createBuildInAttributesEntity(name);
    fillBuiltinQosSnippetLibQosPolicyDurabilityTransientLocal(name);

    name = "BuiltinQosLib::Generic.Common";
    createBuildInAttributesEntity(name);
    fillBuiltinQosLibGenericCommon(name);

    name = "BuiltinQosLib::Generic.StrictReliable";
    createBuildInAttributesEntity(name);
    fillBuiltinQosLibGenericStrictReliable(name);

    name = "BuiltinQosLib::Generic.KeepLastReliable";
    createBuildInAttributesEntity(name);
    fillBuiltinQosLibGenericKeepLastReliable(name);

    name = "BuiltinQosLib::Generic.BestEffort";
    createBuildInAttributesEntity(name);
    fillBuiltinQosLibGenericBestEffort(name);

    name = "BuiltinQosLib::Generic.KeepLastReliable.TransientLocal";
    createBuildInAttributesEntity(name);
    fillBuiltinQosLibGenericKeepLastReliableTransientLocal(name);

    name = "BuiltinQosLib::Pattern.Status";
    createBuildInAttributesEntity(name);
    fillBuiltinQosLibPatternStatus(name);

    name = "BuiltinQosLib::Pattern.LastValueCache";
    createBuildInAttributesEntity(name);
    fillBuiltinQosLibPatternLastValueCache(std::move(name));
}

}  // namespace xmlparser
}  // namespace vbsutil
